我的问题很简单。对那些熟悉RegEx的人来说很简单,不幸的是,我不是。 所以,请帮助我。
我有String
。比方说,"java @aa@ test @bbb@"
。
如果我需要的唯一匹配是,我应该使用什么正则表达式:
1. @aa@
2. @bbb@
我尝试了这个表达式(@(.*)@)
,但结果是:
1. "@aa@ bang @bb@
2. aa@ bang @bb
这离我需要的太远了。
P.S。 另外,我不希望这两个@符号中的@@或空字符串等匹配。
答案 0 :(得分:2)
在我看来,最好的选择是
@[^@]+@
看起来像:
你可以也使用非贪婪的.+?
,但是当你的分隔符只有一个字符(在这种情况下是@
)时,你通常应该更喜欢否定字符阶级方法。
顺便说一下,学习正则表达式的一个很好的资源是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,只有当里面的模式与下一个匹配之前的模式匹配时才允许匹配,而不是在匹配中自己计算。
根据这些,如果您不想获得空匹配,请使用:
@([^@]+)@
或者:
(?<=@)[^@]+(?=@)
由于@(.+?)@
表单也会在匹配中允许@
个字符。