一个奇怪的常规在后面看

时间:2013-05-29 08:28:08

标签: java android regex lookbehind

我编写了一段程序来从“:”(可能没有)和“@”之间的字符串中获取内容并保证订单,例如像“url:123@my.com”这样的字符串,我获取“123”或“123@my.com”然后我也取“123”;所以我写了一个正则表达式来实现它,但我无法工作,背后是第一个版本:

Pattern pattern = Pattern.compile("(?<=:?).*?(?=@)");
Matcher matcher = pattern.matcher("sip:+8610086@dmcw.com");
if (matcher.find()) {
     Log.d("regex", matcher.group());
} else {
     Log.d("regex", "not match");
}

它无法正常工作,因为在第一种情况下:“url:123 @ my.com”它会得到结果:“url:123” 显然不是我想要的:

所以我写第二个版本:

Pattern pattern = Pattern.compile("(?<=:??).*?(?=@)");

但它得到错误,有人说java不支持变量长度在后面;

所以我尝试了第三个版本:

Pattern pattern = Pattern.compile("(?<=:).*?(?=@)|.*?(?=@)");

,其结果与第一个版本相同,但首先应该考虑的第一个条件是什么?

相同
Pattern pattern = Pattern.compile(".*?(?=@)|(?<=:).*?(?=@)");

不是从左到右!我认为我之前理解了正则表达式,但又感到困惑。无论如何,提前感谢。

3 个答案:

答案 0 :(得分:1)

试试这个(稍加编辑,见评论):

String test = "sip:+8610086@dmcw.com";
String test2 = "8610086@dmcw.com";
Pattern pattern = Pattern.compile("(.+?:)?(.+?)(?=@)");
Matcher matcher = pattern.matcher(test);
if (matcher.find()) {
    System.out.println(matcher.group(2));
}
matcher = pattern.matcher(test2);
if (matcher.find()) {
    System.out.println(matcher.group(2));
}

输出:

+8610086
8610086

如果您需要解释该模式,请告诉我。

答案 1 :(得分:0)

正如你所说,你不能在java中做变量lookbehind。

然后,你可以做这样的事情,你不需要lookbehind或lookaround。

正则表达式::?([^@:]*)@

Example在这个例子中(忘了\ n,因为regex101),你将获得你需要的第一组,你不需要做任何特别的事情。有时最简单的解决方案是最好的。

答案 2 :(得分:0)

你真的不需要任何超前或后视。你需要什么可以通过使用贪婪的量子和一些替代来实现:

    .*(?:^|:)([^@]+)

默认情况下,java正则表达式量词(*+{n}?)都是贪婪的(将匹配尽可能多的字符,直到无法找到匹配。在量词之后使用问号可以使它们变得懒惰所以:.*?

您需要为此表达式输出捕获组1,输出捕获组0将返回整个匹配。