使用相同的字符串部分进行正则表达式检查

时间:2015-07-23 06:34:21

标签: java regex string

我对正则表达式很新,但我做了一些研究。 我遇到了一个可能被正则表达式解决的问题,所以我需要一些建议。

我有以下字符串:

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 - 作为一组个人匹配。

当我接近这个问题时,我试图找到一个只匹配相关结果的模式。 所以我想出了:

  • 获取前缀为“key”且前缀为“dog”的数字。

但我不确定它是否可能。我的意思是我知道对于数字2我可以使用1并将其作为结果,但对于其余数字(即(?<=key )+[\d]+),我可以“使用”再次2..5前缀?

4 个答案:

答案 0 :(得分:3)

在Java中,您可以使用接受{n,m}限制量词的约束宽度后视。

所以,你可以使用

(?<=key(?:(?!dog)[^.]){0,100})[0-9]+

或者,如果keydog是整个单词,请使用\b字边界:

String pattern = "(?<=\\bkey\\b(?:(?!\\bdog\\b)[^.]){0,100})[0-9]+";

如果dogkey与数字之间的距离大于m,则可能出现唯一的问题。您可以将其增加到1000,我认为这适用于大多数情况。

示例IDEONE demo

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);

Demo on ideone

答案 2 :(得分:1)

您可以使用正面外观确保您的序列不在除key之外的任何字词之前:

(?<=key)\s(?:\d+[\s,]+)+(?:and )?\d+

请注意,您不需要在dog后面使用负面外观,因为如果您的序列前面有key,此正则表达式将匹配。

请参阅演示https://regex101.com/r/gZ4hS4/3

答案 3 :(得分:1)

您可以2步骤执行此操作。

(?<=key\\s)\\d+(?:\\s*(?:,|and)\\s*\\d+)*

抓住所有数字。参见演示。

https://regex101.com/r/uK9cD8/6

然后splitextract \\d+。请参阅演示。

https://regex101.com/r/uK9cD8/7