Javascript 如何修复这个@提及正则表达式?

Javascript 如何修复这个@提及正则表达式?,javascript,regex,Javascript,Regex,我想捕捉对@usernames的提及。用户名有以下规则: 仅小写字母、数字或点(.) 不是以点开始或结束的 一行中不超过一个点(例如,不允许使用user..name,但不允许使用us.er.name) 所以,我想到了这个: /(?:^|\s)(@)(?!\.)(?!.*\.\.)(?!.*\.[\s|$])([a-z0-9\.]+)(?:\s|$)/gm; 这意味着: (?:^|\s) starting at start of line, or with a whitespace

我想捕捉对@usernames的提及。用户名有以下规则:

  • 仅小写字母、数字或点(.)
  • 不是以点开始或结束的
  • 一行中不超过一个点(例如,不允许使用user..name,但不允许使用us.er.name)
所以,我想到了这个:

/(?:^|\s)(@)(?!\.)(?!.*\.\.)(?!.*\.[\s|$])([a-z0-9\.]+)(?:\s|$)/gm;
这意味着:

 (?:^|\s) starting at start of line, or with a whitespace
         (@) having a @
            (?!\.) name not starting with a dot
                  (?!.*\.\.) not containing two adjacent dots (..)
                            (?!.*\.[\s|$]) not ending with a dot (yes this sucks)
                                          ([a-z0-9\.]+) allowed chars
                                                       (?:\s|$) ending at EOL or whitespace
作为一个完全使用正则表达式的noob,我很高兴看到它在一个长的多行测试字符串中的表现。 但后来我尝试了最简单的测试字符串,如:

@foo @bar I hate you both.
在这种情况下,foo被捕获,但bar没有被捕获。我猜,即使我使用非捕获组,
@foo
也会使用以下空白,因此
@bar
(?:^\s)
时失败

如何编辑此正则表达式以使其正常工作?


请不要建议一个完全不同的@提及正则表达式,我可以很好地搜索它们,因为还有其他问题。我只想让它工作,并知道为什么它不工作。

一般来说,您在这里遇到的问题是,您正在为单词开头和结尾的空格使用捕获组,这意味着这些字符是通过进一步的正则表达式匹配使用的

这是因为您这样做:
(?:…)

相反,您可以使用不使用字符的特殊捕获组类,称为Lookahead:
(?=…)


在正则表达式中,有Lookbehind和Lookahead,分别在正则表达式之前和之后进行检查。对您的问题的完美答案是在字符串的开头使用两个lookback
(?此regexp将完成以下工作:

@[0-9a-z](\.?[0-9a-z])*

如下图所示。

您希望发生什么事情?”@foo@bar“?@Shawn一点也不懂,中间一定有空格。如果使用lookback()的话,正则表达式工作得很好,但我相信你知道Javascript不支持这一点。最好的办法是尝试将lookback转换为lookahead和conditional语句。Twitter上已有一个Javascript库,可以解析如下内容:谢谢。我明天会看,afk now。条件是否“不以点结尾”现在要重写吗?因为尾随空格不再被捕获。我的意思是(?.*\.[\s |$])捕获得很好,您需要将其更改为
(?!\s*\.[\s |$])
,其中它将匹配任何数量的非空格字符,否则为“@foo@bar”找不到任何用户名。我将更新我的答案和示例。您还需要将
(?!.\.\)
从“不包含两个相邻点”更新为
(?!\S*\.\)
@[0-9a-z](\.?[0-9a-z])*