Java + Regex:匹配自定义集合中的字符,这些字符前面没有同一集合中的字符

时间:2015-10-01 01:47:45

标签: java regex

我遇到了Java中的正则表达式的一个愚蠢的问题,我希望将以@开头的字符串与来自某个有效集的字符匹配,但不会出现来自同一有效集的字符。

我想要匹配的术语是:

“y”+ @ +“xxxxxxx”

其中:

  • x是属于有效集[a-zA-Z\\d\\-\\_]
  • 的字符
  • @符号出现一次
  • y是属于有效集[a-zA-Z\\d\\-\\_]
  • 的字符

我目前正尝试使用以下正则表达式

来实现此目的
MY_PATTERN = "[^[A-Za-z\\d\\-\\_]?]" + "@{1}" + "[A-Za-z\\d\\-\\_]+"
String text = "12a@cat123-_     @dog123__- ";
Pattern p = Pattern.compile(PATTERN);
Matcher m = p.matcher(text);

基于此,我希望以下代码仅打印@dog123__-

while(m.find()){ String s = m.group(); System.out.println(s); }

但是它也打印出a@cat123-_

有人可以解释我做错了吗?

3 个答案:

答案 0 :(得分:4)

我假设您尝试匹配的文字可以在任何地方,而不是固定在字符串的开头。

您用于[^[A-Za-z\\d\\-\\_]?]的语法是错误的,并且被解释为其他内容(让我们不进入其中)。否定字符类为[^chars]。所以语法应该是[^A-Za-z\\d\\-_]。但是,要求"@"之前匹配该字符,因此它不会与"@foo"匹配,因为"没有#ta;字符(在"之前不是A-Za-z0-9-_)。

Lookbehinds救援。负后视(?<!subpattern)指定当前位置不以子模式开头。

哦,还有一件事,[A-Za-z\\d\\-_][-\\w]相同(让我们使用更短的版本)。

所以正则表达式应该是:

(?<![-\\w])@[-\\w]+

ideone Demo

答案 1 :(得分:2)

您的模式中存在一些问题,这是应该执行此操作的问题:

(?:^|[^A-Za-z\d\-\_])(@[A-Za-z\d\-\_]+)
  1. @{1}它与@
  2. 相同
  3. [^[A-Za-z\d\-\_]?]问题似乎在这里,您使用的是嵌套字符集,但不起作用
  4. 应为[^A-Za-z\d\-\_]
  5. 您可以将正则表达式简化为:(?:^|[^\w\-])(@[\w\-]+)

    \w匹配任何字母数字字符&amp;下划线

    测试:http://regexr.com/3bt77

    这是javascript,但你不应该有任何问题。

答案 2 :(得分:1)

鉴于以下情况,您的正则表达式可以大大简化:

[a-zA-Z\\d\\-\\_] === [\w-]

所以这就是你想要的:

[^\w-]@[\w-]