在这个问题中:Split text into words problem PHP, complicated problem
答案给出了以下正则表达式,将字符串拆分为单词,意识到小数点和句号之间的区别。
/([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/
这适合我,但我想知道为什么它有效,以便我最终能够自己写这些东西。所以,我的要求是:
请逐步完成该正则表达式并解释每个部分的作用。
答案 0 :(得分:4)
原始问题中的问题是OP想要拆分所有这些特殊字符,但是当字符串中有数字如3.14
的小数点时,问题出现了,他得到了机器人{{1结果中只有3
和14
,而他本身只需要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
希望这有帮助!祝你好运。