正则表达式 - 从匹配中返回上一个和下一个单词

Vok*_*Vok 0 c# regex regex-lookarounds

我目前有两个独立的正则表达式模式来查找目标字+下一个字和目标字+前一个字:

string text = "Here is a test MYWORD statement for MYWORD regex";
string pattern = "(\\bMYWORD\\s)(\\w+)"; //MYWORD statement; MYWORD regex
string pattern = "(\\w+)(\\s\\bMYWORD)"; //test MYWORD; for MYWORD
Run Code Online (Sandbox Code Playgroud)

正则表达式是否提供了一种优雅的方法来将上面的两种模式组合起来用于单个调用?

谢谢

编辑:非常感谢m.buettner和Qtax的精彩解释和示例 - 非常有用!

我已经尝试了一些提供的示例,并且这些在所需的上下文中匹配'MYWORD',但也许我还不够清楚:我试图返回上面评论的所有短语,即:

匹配(模式)应返回以下所有字符串:

'MYWORD statement'
'MYWORD regex'
'test MYWORD'
'for MYWORD'
Run Code Online (Sandbox Code Playgroud)

抱歉,如果我的原始问题没有解释得那么好!

Ala*_*ore 5

在预测中进行比赛:

string pattern = @"\b(?=(\w+\s+MYWORD|MYWORD\s+\w+)\b)";

string[] result = Regex.Matches(text, pattern)
                       .Cast<Match>()
                       .Select(match => match.Groups[1].Value)
                       .ToArray();
Run Code Online (Sandbox Code Playgroud)

此正则表达式在匹配时不消耗任何字符,这使重叠匹配成为可能.您不必担心无限循环,因为正则表达式引擎会在开始寻找下一个匹配之前自动向前突破一个位置.捕获组仍然像平常一样工作.

如果你需要在字符串的开头和结尾处理匹配,就像其他响应者提到的那样,这应该这样做:

string pattern = @"\b(?=((?:^|\w+\s+)MYWORD|MYWORD(?:\s+\w+|$))\b)";
Run Code Online (Sandbox Code Playgroud)

更新:评论者询问如何捕获前面和后面的单词而不包括目标单词.答案结果很简单但不明显:

string pattern = @"\b(?=((\w+)\s+MYWORD|MYWORD\s+(\w+))\b)";

string[] result = Regex.Matches(text, pattern)
                       .Cast<Match>()
                       .Select(match => match.Groups[2].Value + match.Groups[3].Value)
                       .ToArray();
Run Code Online (Sandbox Code Playgroud)

简单的部分是为单个单词添加捕获组.非显而易见的部分是意识到在.NET中,如果捕获组没有参与匹配,并且您访问其Value属性,则会得到一个空字符串.我们知道两组中只有一组会参加每场比赛.我们不需要知道它是哪一个,我们只想要它的价值.连接字符串值可以准确地提供我们想要的内容.

但它变得更好:

string[] result = Regex.Matches(text, pattern)
                       .Cast<Match>()
                       .Select(match => match.Result("$2$3"))
                       .ToArray();
Run Code Online (Sandbox Code Playgroud)

Result()方法没有得到太多使用,因为.NET的Regex API的其余部分设计得非常好,但是当它很有用时,它就很棒了!