负面查找背后没有按预期工作

时间:2018-04-12 08:34:33

标签: java regex regex-negation regex-lookarounds

我不想提取值,如果它来自ex。

高达12 gb - >

12 gb - > 12 gb

正则表达式 - &gt; (?i)(?<!up\s{1}to\s{1})([0-9]{1,})\s*(GB|MB|KB)

输入 - &gt; up to 12 gb output - &gt; 2 gb(未预期)

      up to 1 gb output ->        (expected)

我无法知道如何获得第一次输入的2 gb

2 个答案:

答案 0 :(得分:2)

(?i)(?<!up\s{1}to\s{1})([0-9]{1,})\s*(GB|MB|KB) regex matches 2 gb in 12 gb因为lookbehind在1 char位置失败匹配(因为它前面有up to ,但是,因为正则表达式引擎继续查找字符串内的匹配,它在1之后的下一个位置匹配。

你可以&#34;锚定&#34;单词边界处的匹配(使用\b),或位于非数字((?<![0-9]))之后的位置,例如(?i)\b(?<!\bup\sto\s)\d+\s*[GMK]B,但如果up to和数字之间有0或更多空格,则无效。

使用constrained width lookbehind允许在lookbehinds中使用{min,max)限制量词:

String pat = "(?i)\\b(?<!\\bup\\s{0,100}to\\s{0,100})\\d+\\s*[GMK]B\\b";

请参阅Java demo

List<String> strs = Arrays.asList("up to 1 gb output", "up to 1gb output", "up   to1 gb output", "1 gb output");
Pattern p = Pattern.compile("(?i)\\b(?<!\\bup\\s{0,100}to\\s{0,100})\\d+\\s*[GMK]B\\b");
for (String str : strs) {
    Matcher m = p.matcher(str);
    while (m.find()) {
        System.out.println(str + ": " + m.group(0));
    }
}

输出

1 gb output: 1 gb

模式详情

  • (?i) - 不区分大小写的修饰符
  • \\b - 字边界
  • (?<!\\bup\\s{0,100}to\\s{0,100}) - 在当前位置的左侧,不能是整个单词up,后跟0到100个空格,然后是to,然后是0到100个空格
  • \\d+ - 1+位数(替换为\\d[\\d.]*以匹配浮点数) \\s* - 0+空格
  • [GMK]B - GBMBKB
  • \\b - 字边界。

注意:在模式的开头放置\b字边界,可以提高效率,因为在测试字边界之前不需要检查整个lookbehind模式。

答案 1 :(得分:1)

您可以将此正则表达式用于负面的lookbehind和单词边界:

(?i)(?<!up\sto\s)\b\d+\s*[GMK]B

RegEx Demo

\b在这里很重要,以确保在一个或多个数字之前不断言lookbehind表达式。

另请注意,\s{1}\s相同。