如果值出现在 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
,MB
或KB
-
\\b
- 单词边界。
注意:输入 \b
字边界位于模式的开头,这样可以提高效率,因为在测试字边界之前无需检查整个后向模式。
关于java - 负向查找未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49791706/