我对正则表达式很新,但我做了一些研究。 我遇到了一个可能被正则表达式解决的问题,所以我需要一些建议。
我有以下字符串:
some text key 12, 32, 311 ,465 and 345. some other text dog 612,
12, 32, 9 and 10. some text key 1, 2.
我正在尝试确定是否可以(仅使用正则表达式)提取数字12
32
311
465
345
{{1}仅限} 1
- 作为一组个人匹配。
当我接近这个问题时,我试图找到一个只匹配相关结果的模式。 所以我想出了:
但我不确定它是否可能。我的意思是我知道对于数字2
我可以使用1
并将其作为结果,但对于其余数字(即(?<=key )+[\d]+
),我可以“使用”再次2..5
前缀?
答案 0 :(得分:3)
在Java中,您可以使用接受{n,m}
限制量词的约束宽度后视。
所以,你可以使用
(?<=key(?:(?!dog)[^.]){0,100})[0-9]+
或者,如果key
和dog
是整个单词,请使用\b
字边界:
String pattern = "(?<=\\bkey\\b(?:(?!\\bdog\\b)[^.]){0,100})[0-9]+";
如果dog
或key
与数字之间的距离大于m
,则可能出现唯一的问题。您可以将其增加到1000,我认为这适用于大多数情况。
String str = "some text key 12, 32, 311 ,465 and 345. some other text dog 612,\n12, 32, 9 and 10. some text key 1, 2.";
String str2 = "some text key 1, 2, 3 ,4 and 5. some other text dog 6, 7, 8, 9 and 10. some text, key 1, 2 dog 3, 4 key 5, 6";
Pattern ptrn = Pattern.compile("(?<=key(?:(?!dog)[^.]){0,100})[0-9]+");
Matcher m = ptrn.matcher(str);
while (m.find()) {
System.out.println(m.group(0));
}
System.out.println("-----");
m = ptrn.matcher(str2);
while (m.find()) {
System.out.println(m.group(0));
}
答案 1 :(得分:2)
我不建议使用您无法理解和自定义的代码,但这是我的一次性解决方案,使用the method described in this answer of mine。如果您想了解施工方法,请阅读其他答案。
(?:key(?>\s+and\s+|[\s,]+)|(?!^)\G(?>\s+and\s+|[\s,]+))(\d+)
与其他帖子中描述的方法相比,我放弃了预测,因为在这种情况下,我们不需要检查后缀。
此处的分隔符为(?>\s+and\s+|[\s,]+)
。它目前允许&#34;和&#34;两边都有空格,或任何空格和逗号的混合。我使用(?>pattern)
来抑制回溯,因此交替的顺序很重要。如果您想要修改它并且您不确定自己在做什么,请将其更改回(?:pattern)
。
示例代码:
String input = "some text key 12, 32, 311 ,465 and 345. some other text dog 612,\n12, 32, 9 and 10. some text key 1, 2. key 1, 2 dog 3, 4 key 5, 6. key is dog 23, 45. key 4";
Pattern p = Pattern.compile("(?:key(?>\\s+and\\s+|[\\s,]+)|(?!^)\\G(?>\\s+and\\s+|[\\s,]+))(\\d+)");
Matcher m = p.matcher(input);
List<String> numbers = new ArrayList<>();
while (m.find()) {
numbers.add(m.group(1));
}
System.out.println(numbers);
答案 2 :(得分:1)
您可以使用正面外观确保您的序列不在除key
之外的任何字词之前:
(?<=key)\s(?:\d+[\s,]+)+(?:and )?\d+
请注意,您不需要在dog
后面使用负面外观,因为如果您的序列前面有key
,此正则表达式将匹配。
答案 3 :(得分:1)
您可以2
步骤执行此操作。
(?<=key\\s)\\d+(?:\\s*(?:,|and)\\s*\\d+)*
抓住所有数字。参见演示。
https://regex101.com/r/uK9cD8/6
然后split
或extract \\d+
。请参阅演示。