java - 负向查找未按预期工作

标签 java regex regex-negation regex-lookarounds

如果值出现在 ex 之后,我不想提取值。

高达 12 GB ->

12 GB -> 12 GB

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

输入-> up to 12 gb output -> 2 gb (不是预期的)

      up to 1 gb output ->        (expected)

我无法弄清楚它如何为第一个输入获得 2 GB

最佳答案

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

您可以将匹配“锚定”在单词边界处(使用 \b ),或非数字后面的位置( (?<![0-9]) ),例如(?i)\b(?<!\bup\sto\s)\d+\s*[GMK]B ,但如果 up to 之间有 0 个或多个空格,则它将不起作用以及数量。

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

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.]* 以也匹配 float ) \\s* - 0+ 空格
  • [GMK]B -GB , MBKB
  • \\b - 单词边界。

注意:输入 \b字边界位于模式的开头,这样可以提高效率,因为在测试字边界之前无需检查整个后向模式。

关于java - 负向查找未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49791706/

相关文章:

php - 有没有办法在 PHP 正则表达式中指定 "any character but [aeiou]"?

java - 适用于 Java 的可用 servlet 容器

java - Maven 插件何时可以访问项目类?

python - 从 Python 列表中搜索字符串以查找完全匹配项

javascript - Javascript 中的正则表达式无需回溯即可找到由 @ 包围的数字

java - 为什么这个正则表达式不返回第二个单词

java - Project Explorer 未在 eclipse rcp 应用程序中显示项目

java - 无法到达服务器时程序关闭

javascript - JavaScript中解析 "real"字的正则表达式

java - 正则表达式 : file names that do not contain a word and matches a given pattern