在字符串中获取字符串

时间:2013-10-12 15:22:14

标签: java regex

我的问题很简单。对那些熟悉RegEx的人来说很简单,不幸的是,我不是。 所以,请帮助我。

我有String。比方说,"java @aa@ test @bbb@"。 如果我需要的唯一匹配是,我应该使用什么正则表达式:

1. @aa@
2. @bbb@

我尝试了这个表达式(@(.*)@),但结果是:

1. "@aa@ bang @bb@
2. aa@ bang @bb

这离我需要的太远了。

P.S。 另外,我不希望这两个@符号中的@@或空字符串等匹配。

4 个答案:

答案 0 :(得分:2)

在我看来,最好的选择是

@[^@]+@

看起来像:

Regular expression visualization

Debuggex Demo

可以也使用非贪婪的.+?,但是当你的分隔符只有一个字符(在这种情况下是@)时,你通常应该更喜欢否定字符阶级方法。

顺便说一下,学习正则表达式的一个很好的资源是regular-expressions.info。它从最基本的开始,一直到非常先进。如果您有兴趣了解有关正则表达式的更多信息,我建议您浏览一下。当然,也有特定于Java的Oracle lesson on regular expressions;两者都很棒。


String str = "java @aa@ test @bbb@";

Matcher m = Pattern.compile("@[^@]+@").matcher(str);
while (m.find())
    System.out.println(m.group());
@aa@
@bbb@

答案 1 :(得分:2)

。*贪婪。你应该试试。*?

如果你把?然后reg exp将在第一个@停止,否则它将不会停止,直到它匹配最后一个@(那是贪婪)

答案 2 :(得分:1)

量词默认是贪心的。 .*将消耗所有内容直到最后@。要使其停在第一个@,您需要使用不情愿的量词:

@.+?@

或者否定的字符类也可以起作用:

@[^@]+@

答案 3 :(得分:1)

两个选项:使用非贪婪或使用否定的类。

通过向?添加.*来实现非贪婪:

@(.*?)@

否定课程使用的不是@

@([^@]*)@

顺便说一句,第二个更快。

实际上还有第三种方式:

(?<=@)[^@]*(?=@)

但这可能有点难以理解。


在我看来,你不太了解正则表达式。也许还需要一些解释。

正则表达式中的

.将匹配任何字符,除非它被转义或用于将被视为文字字符的字符类中。

正则表达式中的

*是一个量词,它允许前一个模式匹配0次或更多次;这意味着如果没有什么可以匹配的话,“没有”将匹配,在你的情况下,@中的两个@@之间的任何内容都将匹配,这样你就会得到一个空字符串

+*类似,但不是匹配0次或更多次,而是匹配1次或更多次,这意味着它确保至少匹配1个字符。在你的情况下,使用第二个正则表达式(带有否定的类)与这个量词更有意义:@([^@]+)@

( ... )是一个捕获组,如果匹配,它将存储内部的内容。尝试尽可能地限制它们的使用,因为它会消耗更多的内存/程序在没有它的情况下使用的内存。

[ ... ]是一个字符类,它将匹配里面提到的任何字符。很多正则表达式元字符在其中失去意义,字符类有自己的元字符:^如果放在字符类的开头,这里的字符意思相反; -表示一系列字符,如果它没有被激活或在角色类的四肢。

如上所述,

[^ ... ]是一个否定的类,它将匹配除字符类中的字符之外的所有字符。

(?= ... )是一个积极的先行者,只有当里面的模式匹配上一场比赛后面的内容时才允许匹配,而不是在比赛中自己计算。

(?<= ... )是一个积极的lookbehind,只有当里面的模式与下一个匹配之前的模式匹配时才允许匹配,而不是在匹配中自己计算。


根据这些,如果您不想获得空匹配,请使用:

@([^@]+)@

或者:

(?<=@)[^@]+(?=@)

由于@(.+?)@表单也会在匹配中允许@个字符。