正则表达式词边界混乱

时间:2016-04-27 06:09:12

标签: .net regex

从我读到的内容来看,我想捕捉到可以使用单词边界的特定单词。

我有以下信息

router.navigateXxx()

我使用了以下正则表达式,当我需要匹配First: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key1 Key2 Key3 Key4 Second: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key5 Key3 Key6 Third: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key7 Key6 时,它只匹配Key7

Key3 Key4 Key6 Key7

2 个答案:

答案 0 :(得分:1)

试试这个

(?:#\d{4}|\G)\s(\b(?:Key3|Key4|Key6|Key7)\b)

Regex demo

或者

(?:#\d{4}|\G) \b(?:(Key3|Key4|Key6|Key7)|\w+)\b

Regex demo

<强>解释
(?: … ):非捕获组sample
\:逃脱一个特殊字符sample
|:替代/或操作数sample
\G:字符串的开头或上一个匹配的结尾sample
\s:“空格字符”:空格,制表符,换行符,回车符,垂直制表符sample
( … ):捕获小组sample

答案 1 :(得分:1)

问题是你的正则表达式不会让# + 4位数字和你感兴趣的键之间有任何关系。你可以通过在lookbehind中添加一个可选的(?:\s+\w+)*模式来轻松修复它。将匹配1个以上空格和1个以上字符的零个或多个序列:

(?<=#\d{4}(?:\s+\w+)*)\s*\b(Key3|Key4|Key6|Key7)\b
          ^^^^^^^^^^^  

请参阅regex demo,在C#中使用逐字字符串文字声明(或在VB.NET中按原样使用)并与Regex.Matches一起使用。

A C# demo

var strs = new List<string> { "First: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key1 Key2 Key3 Key4",
"Second: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key5 Key3 Key6",
"Third: 12345Z Apr 16 Something WORD: ABC Notification #1234 Key7 Key6"};
foreach (var s in strs) {
    var result = Regex.Matches(s, @"(?<=#\d{4}(?:\s+\w+)*)\s*\b(Key3|Key4|Key6|Key7)\b")
        .Cast<Match>()
        .Select(m => m.Value)
        .ToList();
    foreach (var e in result)
        Console.WriteLine(e);
}