c# - 将字符串拆分为单词并重新加入其他数据

标签 c# asp.net regex string

我有一个使用 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...
    }

理想情况下,需要保留每个单词周围的间距。下面的伪示例显示了我正在尝试做的事情。

  1. 将原始短语拆分成单词
  2. 将每个单词包装在一个正则表达式模式中,以保留空间 匹配时
  3. 重新加入单词模式以生成将用于 匹配

    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/

相关文章:

c# - 无法更新 Entity Framework 6 中的外键

c# - Asp.net 网站速度非常慢,因为每个页面都有角色 checkin

ASP.NET 图表控件 - 如何自动绘制空白图表区域?

具有多种模式的 Python re.findall

java - 正则表达式查找带方括号的字符串并替换

c# - 如何在表单应用程序中显示控制台输出/窗口?

c# - 我应该使用不同的对象来锁定每个属性吗?

c# - 处理类中创建事件的最简单方法

c# - Membership.GetUser 结果导致对象引用未设置为对象的实例

javascript - 匹配来自单个正则表达式的文件名和文件扩展名