需要了解正则表达式作为另一个查询的答案发布

时间:2013-11-15 16:57:17

标签: regex

在这个问题中:Split text into words problem PHP, complicated problem

答案给出了以下正则表达式,将字符串拆分为单词,意识到小数点和句号之间的区别。

/([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/

这适合我,但我想知道为什么它有效,以便我最终能够自己写这些东西。所以,我的要求是:

请逐步完成该正则表达式并解释每个部分的作用。

3 个答案:

答案 0 :(得分:4)

原始问题中的问题是OP想要拆分所有这些特殊字符,但是当字符串中有数字如3.14的小数点时,问题出现了,他得到了机器人{{1结果中只有314,而他本身只需要3.14

确定我们当前的问题,让我们把你的表达分成几部分:

/([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/
                             ^   ^              ^

正如您所看到的,正则表达式使用了一个替换,因此它匹配第一个[\s_;?!\/\(\)\[\]{}<>\r\n"],第二个\.$,第三个(?<=\D)[:,.\-]或第四个{{1} }}

第一部分:[:,.\-](?=\D))

此符号与以下字符之一匹配:空格[\s_;?!\/\(\)\[\]{}<>\r\n"]_;?!/()[]{}<,回车>,换行符\r\r

第二部分":仅当位于字符串结尾处时才匹配点

第三部分:\.$这符合以下任何字符(?<=\D)[:,.\-]:,.,只要它们不在数字-,因此(?<=\D)3.14之类的内容不会导致分割。

第四部分和最后一部分:23:23只要符合以下字符[:,.\-](?=\D):,.,就会匹配以下任意字符-由一个不是数字(?=\D)的字符。

此规则是对第三条规则的补充。

答案 1 :(得分:3)

这个正则表达式的四个替代部分,解释......

[\s_;?!\/\(\)\[\]{}<>\r\n"]

第1部分:似乎是试图匹配任何非字母,数字或潜在的数字分隔符(其中包含更多内容)。

\.$

第2部分:在字符串末尾匹配句点/句号。

(?<=\D)[:,.\-]|[:,.\-](?=\D)

第3/4部分:匹配数字分隔符(冒号,逗号,句号/句号,减号),前提是它前面或后面跟一个非数字字符。

答案 2 :(得分:3)

只是添加以供将来参考,如果您使用该工具解析表达式并将其分解为多个网站Explain Regular Expression,则会显示以下说明。

首先使用起始斜杠/和结尾斜杠/作为分隔符。

分隔符可以是任何非字母数字非反斜杠非空白字符

你的正则表达式:

(                              group and capture to \1:
 [\s_;?!\/\(\)\[\]{}<>\r\n"]   any character of: whitespace (\n, \r, \t, \f, and " "), 
                               _ ; ? ! \/ \( \) \[ \] { } < > \r \n "
|                              OR
 \.                            '.'
  $                            before an optional \n, and the end of the string
  |                            OR
  (?<=                         look behind to see if there is:
    \D                         non-digits (all but 0-9)
  )                            end of look-behind
  [:,.\-]                      any character of: ':', ',', '.', '\-'
  |                            OR
  [:,.\-]                      any character of: ':', ',', '.', '\-'
  (?=                          look ahead to see if there is:
    \D                         non-digits (all but 0-9)
  )                            end of look-ahead
)                              end of \1

基本上,你的角色类中有\r\n并且可以删除该部分,因为\s将自己匹配。通常只有某些角色需要在角色类中进行转义。

(?:[(){}\[\]<>\/!?;_"\s]|\.$|(?<=\D)([;.,-])|(?1)(?=\D))

请参阅demo

希望这有帮助!祝你好运。