我的问题很简单。对于那些熟悉 RegEx 的人来说很简单,不幸的是,我不是。所以,请帮我解决这个问题。
我有String。比方说,"java @aa@ test @bbb@"。如果我需要的唯一匹配项是,我应该使用什么正则表达式:
1. @aa@
2. @bbb@
我尝试了这个表达式(@(.*)@),但结果是:
1. "@aa@ bang @bb@
2. aa@ bang @bb
这离我需要的太远了。
PS 另外,我不希望在这两个 @ 符号内匹配 @@ 或空字符串。
在我看来,最好的选择是
@[^@]+@
看起来像:

您也可以使用 non-greedy .+?,但是当您的分隔符只有一个字符(在这种情况下@)时,您通常应该更喜欢否定字符类方法。
顺便说一句,学习正则表达式的一个很好的资源是regular-expressions.info。它从最基本的开始,一直到非常高级。如果您有兴趣了解有关正则表达式的更多信息,我敦促您浏览一下。当然,还有关于正则表达式的特定于 Java 的 Oracle 课程;两者都很棒。
String str = "java @aa@ test @bbb@";
Matcher m = Pattern.compile("@[^@]+@").matcher(str);
while (m.find())
System.out.println(m.group());
@aa@ @bbb@
.* 是贪婪的。你应该试试 。*?
如果你把 ? 那么 reg exp 将在第一个 @ 处停止,否则它不会停止,直到它匹配最后一个 @(这是贪婪)
量词默认是贪婪的。.*将消耗一切直到最后@。为了让它停在第一个@,你需要使用不情愿的量词:
@.+?@
或者也可以使用否定字符类:
@[^@]+@
两种选择:使用非贪婪或使用否定类。
非贪婪是通过在 中添加 a?来实现的.*:
@(.*?)@
否定类正在使用所有内容而不是@:
@([^@]*)@
顺便说一下,第二个更快。
其实还有第三种方式:
(?<=@)[^@]*(?=@)
但这可能有点难以理解。
在我看来,您不太了解正则表达式。也许需要更多的解释。
.in regex 将匹配任何字符,除非它被转义或在将被视为文字字符的字符类中使用。
*在 regex 中是一个量词,它允许前一个模式匹配 0 次或更多次;这意味着如果没有可匹配的内容,则将匹配“无”,并且在您的情况下,将匹配两者之间的任何内容,@以便@@您得到一个空字符串作为结果。
+类似于*,除了匹配 0 次或多次,而是匹配 1 次或多次,这意味着它确保至少有 1 个字符要匹配。在您的情况下,将第二个正则表达式(带有否定类)与此量词一起使用会更有意义:@([^@]+)@
( ... )是一个捕获组,如果有匹配,它将存储里面的内容。尽量限制这些的使用,因为它会消耗更多的内存,否则你的脚本/程序会在没有它的情况下使用。
[ ... ]是一个字符类,它将匹配里面提到的任何字符。很多正则表达式元字符在内部失去了意义,字符类有自己的元字符:^如果放在字符类的开头,这意味着与字符相反;并且-表示一系列字符,如果它没有被排除或在字符类的末端。
[^ ... ]如上所述是一个否定类,它将匹配除字符类中的所有字符之外的所有字符。
(?= ... )是一个积极的前瞻,只有当里面的模式与前一个匹配之后的匹配时才允许匹配,而不将它们计入匹配本身。
(?<= ... )是一个正向的lookbehind,仅当内部的模式与下一个匹配之前的匹配时才允许匹配,而不将它们计入匹配本身。
从这些中,如果您不想得到空匹配,请使用:
@([^@]+)@
或者:
(?<=@)[^@]+(?=@)
由于@(.+?)@表单也将允许@匹配字符。