【问题标题】:Regex word boundaries capturing wrong words正则表达式单词边界捕获错误单词
【发布时间】:2015-12-02 05:12:19
【问题描述】:

试图让我在 C# 中的简单 Regex 语句按我想要的方式工作时遇到了一些困难。

如果我有一个长字符串并且我想找到“执行”这个词但 NOT“执行”我认为我的正则表达式看起来像这样:

Regex.IsMatch(input, string.Format(@"\b{0}\b", "executive");

但是,这仍然匹配仅包含 executives 而不是 executive(单数)的输入。

我认为正则表达式中的单词边界在正则表达式文本的开头和结尾使用时,会指定您想要匹配该单词而不是该单词的任何其他形式? p>

编辑:为了澄清发生了什么,我试图在Students 中找到所有包含executiveNotes,并忽略仅包含“执行”的单词。如下:

var studentMatches =
    Students.SelectMany(o => o.Notes)
        .Where(c => Regex.Match(c.NoteText, string.Format(@"\b{0}\b", query)).Success).ToList();

在这种情况下,query 将是“执行”。

奇怪的是,虽然我不希望上面的代码匹配 executives,但下面的代码将 (也就是我期望它做的事情):

foreach (var stu in Students)
{
    foreach (var note in stu.Notes)
    {

        if (Regex.IsMatch(note.NoteText, string.Format(@"\b{0}\b", query)))
            Console.WriteLine(stu.LastName);
    }
}

为什么具有相同正则表达式代码的嵌套 for 循环会产生准确的匹配,而 linq 表达式似乎想要返回包含我正在搜索的单词的任何内容?

【问题讨论】:

  • @PranavCBalan 是的,我已经读过了,他们的 \b4\b 示例实际上与我所拥有的相同,只是他们的示例与“44”不匹配,而我的则匹配(执行与高管)
  • 高管们正在回归什么样的模式?鉴于您的代码,我无法让它发生。
  • @Tom 我已经编辑了我的帖子以便澄清
  • 我仍然怀疑其他一些与正则表达式无关的问题。我会在 var studentMatches 出现正则表达式的行上放置一个断点,然后查看 query 的值是什么。
  • @Tom 查询如“执行”?或者你指的是NoteText?因为它是一个控制台应用程序,我每次都手动输入“executive”作为搜索查询。是否可以在我的输入帮助中调用 Trim()?

标签: c# regex


【解决方案1】:

您的 linq 查询会产生正确的结果。所见即所得。

让我们给出适当的名称以使其清楚

var noteMatches = Students.SelectMany(student => student.Notes)
    .Where(note => Regex.Match(note.NoteText, string.Format(@"\b{0}\b", query)).Success)
    .ToList();

在执行SelectMany 之后的这个查询中,我们收到了所有笔记的扁平化列表。因此丢失了关于哪个笔记属于哪个学生的信息。

同时,在带有foreach 循环的示例代码中,您会输出有关学生的信息。

我可以假设您需要如下查询

var studentMatches = Students.Where(student => student.Notes
        .Any(note => Regex.IsMatch(note.NoteText, string.Format(@"\b{0}\b", query))))
    .ToList();

但是,如果同一个学生的笔记同时包含 executiveexecutives,则不清楚您希望获得什么结果。

【讨论】:

  • 对不起我的英语不好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 2012-09-24
  • 1970-01-01
  • 2022-07-06
  • 2021-06-09
  • 2013-02-11
相关资源
最近更新 更多