2010-08-23 21 views
2

我有一个正则表达式匹配的用户名(其功能在PHP中使用preg_match):正则表达式不一样在PHP

/[a-z]+(?(?=\-)[a-z]+|)\.[1-9][0-9]*/ 

该图案匹配的形式的abc.124abc-abc.123等用户名

然而,当我把这个给JavaScript:

var re = new RegExp("/[a-z]+(?(?=\-)[a-z]+|)\.[1-9][0-9]*/"); 

我收到一个语法错误:

SyntaxError: Invalid regular expression: /[a-z]+(?(?=-)[a-z]+|).[1-9][0-9]*/: Invalid group 

(?(?=\-)[a-z]+|)是说,如果[a-z]+后,我们看到了-然后断言[a-z]+是后否则,比赛什么都没有。这一切在PHP中都很好用,但是我对JavaScript有什么不同?

编辑:我很欣赏的意见,现在我对此还有最后一个问题:

var str="accouts pending removal shen.1206"; 
    var patt= new RegExp("/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/"); 
    var result=patt.exec(str); 
    alert(result); 

此警报出来作为null?但是,如果我按照以下方式工作:

var patt=/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/; 
var result=patt.exec(str); 
alert(result); 

为什么“新的RegExp()”不起作用?

+0

Javascript不支持条件''(部分 – NullUserException 2010-08-23 17:49:46

+0

像JS中'new'的大多数其他用法一样,我避免使用'new RegExp'。请注意,到目前为止发布的两个答案都是使用文字形式而不是' new':https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions – JAL 2010-08-23 17:51:06

回答

5

不同的正则表达式引擎支持不同的功能。 Conditionalsnot supported的Javascript。

无论如何,条件对你的模式是不必要的。我会简化你的表达到/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/,这是更容易理解,并将在PHP的PCRE和Javascript中工作。

3

JavaScript不使用与PHP相同的正则表达式实现。在这种情况下,JavaScript不支持条件表达式(?(?=regex)then|else)(请参阅comparison of regular expression flavors)。但是你可以使用下面的正则表达式等同于你:

/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/ 

并采用RegExp构造函数来创建正则表达式(而不是regular expression literal syntax /…/)时,你需要躲避逃逸\了。因此:

var re = /[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/;     // OR 
var re = new RegExp("/[a-z]+(?:-[a-z]+)?\\.[1-9][0-9]*/"); 
2

即使在PHP中,您的条件也不起作用。前瞻 - (?=-) - 如果下一个字符是连字符,则成功,但不会连续使用连字符。然后[a-z]+尝试匹配相同的位置并失败,因为下一个字符仍然是-。你将不得不再次匹配连字符 - -[a-z]+ - 但正如其他人所说,你不应该使用条件反正。

条件是诱人的;他们似乎像他们应该是非常有用的,但在实践中,他们很少。他们通过反映我们自然思考某些问题的方式引诱我们:“我想匹配一些字母,并且如果跟在它们后面的字符是连字符,我想匹配它和更多的字母。“

如果你学会思考更像一个正则表达式,你会省下很多麻烦:”我想匹配一大堆字母,可选地后跟一个连字符和更多的字母。“实际上,正则表达式写到自己:

/[a-z]+(?:-[a-z]+)?/ 

(您正则表达式的\.[1-9][0-9]*部分是罚款,我离开了,所以我可以专注于条件方面。)


编辑:要回答的问题评论,是的,你的正则表达式匹配两种形式的字符串:abc.124abc-abc.123。但是看看到底是哪一部分它匹配的字符串

Array 
(
    [0] => Array 
     (
      [0] => abc.124 
      [1] => abc.123 
     ) 

) 

什么情况是,第一[a-z]+最初匹配abc-abc.123第一abc。然后,前视符合-而不消耗它,第二个[a-z]+试图匹配连字符并失败,正如我前面所述。

在该位置未能找到匹配项,正则表达式引擎开始一次向前碰撞一个字符并再次尝试。当它到达第二个abc时,第一个[a-z]+与它匹配,并转交给正则表达式的下一部分,即条件。

输入字符串中的下一个字符是.,所以向前查看失败。条件不需要匹配任何内容,因为您没有为else子句提供子模式。所以条件不匹配,控制传递给正则表达式的下一部分,即\.[1-9][0-9]*,这成功了。

+0

php> echo preg_match(“/ [az] +(?(?= \ - )[az] + |)\。[1 -9] [0-9] * /“,”sh-sh.123“); // echos 1 这对php不起作用么? – Chris 2010-08-24 11:04:20

+1

@Chris:看到我的扩展答案 – 2010-08-24 14:30:56

+0

感谢扩展,欣赏它并学到了一些东西。 – Chris 2010-08-24 14:50:03