简体   繁体   English

正则表达式仅在文本包含以下内容时匹配

[英]Regex match only if text contains something before

Given the following text 给出以下文字

KEYWORD This is a test
We want to match the following groups 1:YES 2:YES 3:YES

I want to match with " 1:YES ", " 2:YES " and " 3:YES " using 我想使用“ 1:YES ”,“ 2:YES ”和“ 3:YES ”进行匹配

((\d):YES)

If and only if the first word in the complete text is " KEYWORD " 当且仅当全文中的第一个单词是“ KEYWORD ”时

Given this test: 鉴于此测试:

This is a test
We want to match the following groups 1:YES 2:YES 3:YES

No matches should be found 找不到匹配项

Java (as with most regex engines) doesn't support unbounded length look behinds, however there is a work-around! Java(与大多数正则表达式引擎一样)不支持无限长度的回头看,但是有一种解决方法!

String str = "KEYWORD This is a test\n" +
        "We want to match the following groups 1:YES 2:YES 3:YES";
Matcher matcher = Pattern.compile("(?s)(?<=\\AKEYWORD\\b.{1,99999})(\\d+:YES)").matcher(str);
while (matcher.find()) {
    System.out.println(matcher.group(1));
}

Which outputs: 哪个输出:

1:YES
2:YES
3:YES

The trick here is the look behind (?<=\\\\AKEYWORD.{1,99999}) which has a large (but not unbounded) length. 这里的窍门是后面的样子(?<=\\\\AKEYWORD.{1,99999}) ,它的长度很大(但不是无限)。 (?s) means DOTALL flag (dot matches newline too) and \\A means start of input which is needed because ^ matches start of line when DOTALL flag is used. (?s)表示DOTALL标志(点也与换行符匹配), \\A表示需要开始输入,因为使用DOTALL标志时^匹配行的开头。

Without tricking lookbhinds in Java you can capture \\d+:YES\\b strings with using \\G . 无需在Java中欺骗别人,就可以使用\\G捕获\\d+:YES\\b字符串。 \\G causes a match to start from where previous match ended or it will match beginning of string the same as \\A . \\G使匹配从上一个匹配结束的地方开始,或者匹配与\\A相同的字符串的开头。

We are in need of its first capability: 我们需要它的第一个功能:

(?:\AKEYWORD|\G(?!\A))[\s\S]*?(\d:YES\b)

Breakdown: 分解:

  • (?: Start of non-capturing group (?:非捕获组的开始
    • \\A Match beginning of subject string \\A匹配主题字符串的开头
    • KEYWORD Match keyword KEYWORD匹配关键字
    • | Or 要么
    • \\G(?!\\A) Continue from where previous match ends \\G(?!\\A)从上一场比赛结束的地方继续
  • ) End of NCG ) NCG结束
  • [\\s\\S]*? Match anything else un-greedily 贪婪地匹配其他任何内容
  • (\\d+:YES\\b) Match and capture our desired part (\\d+:YES\\b)匹配并捕获我们想要的部分

Live demo 现场演示

Java code: Java代码:

Pattern p = Pattern.compile("(?:\\AKEYWORD|\\G(?!\\A))[\\s\\S]*?(\\d+:YES\\b)");
Matcher m = p.matcher(string);                                   
while (m.find()) {
    System.out.println(m.group(1));
}

Live demo 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM