【问题标题】:C# - Regex Match whole wordsC# - 正则表达式匹配整个单词
【发布时间】:2011-08-07 05:08:30
【问题描述】:

我需要匹配包含给定字符串的所有单词。

string s = "ABC.MYTESTING
XYZ.YOUTESTED
ANY.TESTING";

Regex r = new Regex("(?<TM>[!\..]*TEST.*)", ...);
MatchCollection mc = r.Matches(s);

我需要的结果是:

MYTESTING
YOUTESTED
TESTING

但我明白了:

TESTING
TESTED
.TESTING

如何使用正则表达式实现这一点。

编辑:扩展示例字符串。

【问题讨论】:

    标签: c# regex regex-negation


    【解决方案1】:

    如果您要查找包括“TEST”在内的所有单词,则应使用

    @"(?<TM>\w*TEST\w*)"
    

    \w 包含单词字符,是 [A-Za-z0-9_] 的缩写

    【讨论】:

    • @tvr:注意\w 匹配 [0-9a-zA-Z_]。如果您不想要数字或下划线,请坚持使用\b
    • @Brad:匹配的远不止这些,但重要的是它匹配非单词字符。
    【解决方案2】:

    保持简单:为什么不尝试 \w*TEST\w* 作为匹配模式。

    【讨论】:

      【解决方案3】:

      我得到了您期望的结果:

      string s = @"ABC.MYTESTING
      XYZ.YOUTESTED
      ANY.TESTING";
      
      var m = Regex.Matches(s, @"(\w*TEST\w*)", RegexOptions.IgnoreCase);
      

      【讨论】:

      • +1 表示逐字字符串和(可能)正确的正则表达式,但 RegexOptions.Multiline 在这里没有用处。
      • @alan 是的,现在已删除。这是从我的 LINQPad 脚本中偷偷进来的。
      • 是的,RegexBuddy 也总是偷偷溜进去。很烦人。
      【解决方案4】:

      尝试使用\b。它是非单词分隔符的正则表达式标志。如果你想匹配两个词,你可以使用:

      /\b[a-z]+\b/i
      

      顺便说一句,.net 不需要周围的/i 只是一个不区分大小写的匹配标志。

      .NET 替代方案:

      var re = new Regex(@"\b[a-z]+\b", RegexOptions.IgnoreCase);
      

      【讨论】:

      • 这匹配一个 1 个字母的单词,而不是两个单词。
      • 嗯。我该如何指定?我试过这个但不起作用:Regex r = new Regex("\b(?[!\..]*TEST.*)\b", ...);
      • @mousino:确实我错过了一个量词,但会匹配两个词。
      • @tvr:另外,如果您只想要以“TEST”开头的单词,请使用\btest[a-z]+\b,例如ideone.com/8KNQz
      • @Brad 感谢您的示例代码。这是一个较大的正则表达式的一小部分,我现在无法更改..
      【解决方案5】:

      使用组我认为你可以实现它。

              string s = @"ABC.TESTING
              XYZ.TESTED";
              Regex r = new Regex(@"(?<TM>[!\..]*(?<test>TEST.*))", RegexOptions.Multiline);
              var mc= r.Matches(s);
              foreach (Match match in mc)
              {
                  Console.WriteLine(match.Groups["test"]);
              }
      

      完全按照您的意愿工作。

      顺便说一句,您的正则表达式模式应该是逐字字符串 (@"")

      【讨论】:

      • 这里不需要Multiline 选项,但可能需要IgnoreCase。关于[!\..]*,请看我的回答。
      • 是的,但我只是使用 OP 提供的模式。提供的其他模式更好。
      • 听我说:从不在不验证问题的情况下使用正则表达式是个好主意。或者 any 代码,就此而言。或从其他答案。我被这样烧过太多次了。 :-/
      【解决方案6】:
      Regex r = new Regex(@"(?<TM>[^.]*TEST.*)", RegexOptions.IgnoreCase);
      

      首先,正如@manojlds 所说,您应该尽可能使用逐字字符串作为正则表达式。否则,您将不得不在大多数正则表达式转义序列中使用两个反斜杠,而不仅仅是一个(例如 [!\\..]*)。

      其次,如果您想匹配除点以外的任何内容,则正则表达式的该部分应为[^.]*^ 是反转字符类的元字符,而不是 !,并且. 在该上下文中没有特殊含义,因此不需要转义。但是您可能应该改用\w*,甚至[A-Z]*,这取决于您所说的“单词”到底是什么意思。 [!\..] 匹配 !.

      Regex r = new Regex(@"(?<TM>[A-Z]*TEST[A-Z]*)", RegexOptions.IgnoreCase);
      

      这样你就不需要担心单词边界了,尽管它们并没有什么坏处:

      Regex r = new Regex(@"(?<TM>\b[A-Z]*TEST[A-Z]*\b)", RegexOptions.IgnoreCase);
      

      最后,如果你总是拿整场比赛,你不需要使用捕获组:

      Regex r = new Regex(@"\b[A-Z]*TEST[A-Z]*\b", RegexOptions.IgnoreCase);
      

      匹配的文本将通过 Match 的 Value 属性提供。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-15
        • 2012-01-06
        • 2017-07-08
        相关资源
        最近更新 更多