两个正则表达式之间的差异

时间:2013-12-27 19:31:32

标签: php regex unicode

有人知道为什么这个正则表达式:

/^(([a-zA-Z0-9\(\)áéíóúÁÉÍÓÚñÑ,\.°-]+ *)+)$/

有效,但这个没有:

/^(([a-zA-Z0-9áéíóúÁÉÍÓÚñÑ,\.°-\(\)]+ *)+)$/

不同之处在于括号的位置......我尝试使用一些在线PHP正则表达式测试程序并获得相同的结果。第二个根本不起作用......

PHP返回:

preg_match(): Compilation failed: range out of order in character class at offset 44 in...

这不是一个批评问题,因为我已经设法让它发挥作用,但我有好奇心!

也许unicode角色正在改变什么?

3 个答案:

答案 0 :(得分:4)

当在括号内使用-字符(表示字符集)时,它表示一个范围,除非它是集合中的最后一个字符,集合中的第一个字符,或者直接在打开否定字符之后。然后它意味着文字冲刺。通过将它从末端移动到中间,你改变了它的含义。如果你想把它放在中间,你需要逃避它:\-

答案 1 :(得分:1)

如果将连字符作为字符类中的第一个或最后一个字符放置,则将其视为文字-(而不是范围),因此不需要转义。

这些是连字符不需要转义的位置:

  • 在开始括号([)或
  • 之后
  • 在结束括号(])或
  • 之前
  • 在否定插入符号(^
  • 之后

在第二个正则表达式中,您将连字符放在中间,正则表达式引擎尝试创建一个范围,其中包含连字符前面的字符,连字符后面的字符以及它们之间的所有字符。数字顺序。由于这样的范围是不可能的,因此会触发错误消息。有关字符表,请参阅asciitable.com

将连字符放在表达式的最后位置实际上导致它不需要转义,因为它不能成为范围的一部分,但是你可能仍然想要养成总是逃避它的习惯。

答案 2 :(得分:0)

在你的第一个正则表达式中,你已经正确地管理了所有事情,即使是-连字符也在它的末尾。它也应该在那里!我的意思是它有两个地方,如果你不想逃避它,一个地方在char类的末尾,另一个地方在char类的开头!

你猜对了!否则你应该逃避它!