我有一个使用 Regex
来查找文本 string
中的模式的方法。它有效,但还不够完善,因为它要求文本以确切的顺序出现,而不是将短语视为一组单词。
public static string HighlightExceptV1(this string text, string wordsToExclude)
{
// Original version
// wordsToExclude usually consists of a 1, 2 or 3 word term.
// The text must be in a specific order to work.
var pattern = $@"(\s*\b{wordsToExclude}\b\s*)";
// Do something to string...
}
这个版本改进了以前的版本,因为它确实允许以任何顺序匹配单词,但是它在最终输出中导致了一些间距问题,因为间距被删除并替换为管道。
public static string HighlightExceptV2(this string text, string wordsToExclude)
{
// This version allows the words to be matched in any order, but it has
// flaws, in that the natural spacing is removed in some cases.
var words = wordsToExclude.Replace(' ', '|');
var pattern = $@"(\s*\b{words}\b\s*)";
// Example phase: big blue widget
// Example output: $@"(\s*\bbig|blue|widget\b\s*)"
// Do something to string...
}
理想情况下,需要保留每个单词周围的间距。下面的伪示例显示了我正在尝试做的事情。
- 将原始短语拆分成单词
- 将每个单词包装在一个正则表达式模式中,以保留空间 匹配时
重新加入单词模式以生成将用于 匹配
public static string HighlightExceptV3(this string text, string wordsToExclude) { // The outputted pattern must be dynamic due to unknown // words in phrase. // Example phrase: big blue widgets var words = wordsToExclude.Replace(' ', '|'); // Example: big|blue|widget // The code below isn't complete - merely an example // of the required output. var wordPattern = $@"\s*\b{word}\b\s*"; // Example: $@"\s*\bwidget\b\s*" var phrasePattern = "$({rejoinedArray})"; // @"(\s*\bbig\b\s*|\s*\bblue\b\s*|\s*\bwidget\b\s*)"; // Do something to string... }
注意:可能有更好的方法来处理单词边界间距,但我不是正则表达式专家。
我正在寻找一些帮助/建议来获取拆分数组、包装它,然后以最简洁的方式重新加入它。
最佳答案
您需要将所有备选方案包含在非捕获组中,(?:...|...)
.此外,为了进一步解决最终问题,我建议用它们的环视明确等效项 (?<!\w)...(?!\w)
替换单词边界。 .
这是一个working C# snippet :
var text = "there are big widgets in this phrase blue widgets too";
var words = "big blue widgets";
var pattern = $@"(\s*(?<!\w)(?:{string.Join("|", words.Split(' ').Select(Regex.Escape))})(?!\w)\s*)";
var result = string.Concat(Regex.Split(text, pattern, RegexOptions.IgnoreCase).Select((str, index) =>
index % 2 == 0 && !string.IsNullOrWhiteSpace(str) ? $"<b>{str}</b>" : str));
Console.WriteLine(result);
注意事项
-
words.Split(' ').Select(Regex.Escape)
- 拆分words
带空格的文本和正则表达式转义每个项目 -
string.Join("|",...)
重新构建字符串插入|
项目之间 -
(?<!\w)
否定后视匹配一个没有紧跟单词 char 的位置,并且(?!\w)
否定先行匹配一个没有紧跟单词 char 的位置。
关于c# - 将字符串拆分为单词并重新加入其他数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56037857/