繁体   English   中英

JavaScript中的正则表达式与PHP中的正则表达式不同

[英]Regular expression in JavaScript not the same as in 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

(?(?=\\-)[az]+|)是说如果在[az]+之后我们看到-然后断言[az]+在它之后,否则不匹配。 这在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()”不起作用?

不同的正则表达引擎支持不同的功能 Javascript 不支持 条件

无论如何,您的模式不需要条件。 我会将你的表达简化为/[az]+(?:-[az]+)?\\.[1-9][0-9]*/ ,这更容易理解,并且可以在PHP的PCRE和的JavaScript。

JavaScript不像PHP那样使用相同的正则表达式实现。 在这种情况下,JavaScript不支持条件表达式(?(?=regex)then|else) (请参阅正则表达式flavor的比较 )。 但是您可以使用以下与您的正则表达式相同的正则表达式:

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

当使用RegExp构造函数创建正则表达式(而不是正则表达式文字语法/…/ )时,您还需要转义转义\\ 所以:

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

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

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

如果你学会更像一个正则表达式,你会省去很多麻烦:“我想要匹配一大块字母,可选地后跟连字符和更多字母。” 正则表达式实际上写道:

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

\\.[1-9][0-9]*你的正则表达式的一部分很好;我把它留下了所以我可以专注于条件方面。)


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

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

)

会发生的是,第一个[az]+最初与abc-abc.123中的第一个abc匹配。 然后前瞻匹配-没有消耗它,第二个[az]+尝试匹配连字符并失败,正如我之前所说。

由于未能在该位置找到匹配项,正则表达式引擎会一次开始向前突出一个字符并再次尝试。 当它到达第二个abc ,第一个[az]+匹配它并移交到正则表达式的下一部分,即条件。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM