Php 仅拆分特殊字符上的文本,但不拆分带小数点的数字
我正在考虑PHP中一个特殊的regexp问题,但我找不到解决方案。 我尝试将一些文本拆分为术语,以获得简单的单词、数字和网址 所以我决定对每个非字母数字字符(\w)进行拆分 为了使用不同的语言,我将\w与其他字母一起使用,如Ääè等 例如:Php 仅拆分特殊字符上的文本,但不拆分带小数点的数字,php,regex,Php,Regex,我正在考虑PHP中一个特殊的regexp问题,但我找不到解决方案。 我尝试将一些文本拆分为术语,以获得简单的单词、数字和网址 所以我决定对每个非字母数字字符(\w)进行拆分 为了使用不同的语言,我将\w与其他字母一起使用,如Ääè等 例如: 20,000 15.20 This is at Text. Right?! www.google.com Jean Béraud 到目前为止,我使用以下regexp分割文本: [^\w(äÄüÜöÖßèé)] 这在80%的情况下运行良好,但将20000
20,000 15.20 This is at Text. Right?!
www.google.com Jean Béraud
到目前为止,我使用以下regexp分割文本:
[^\w(äÄüÜöÖßèé)]
这在80%的情况下运行良好,但将20000分为20000个,将www.google.com分为www.google.com
所以我试着把数字放在一起,但还是在点上分开,比如Text.
得到Text
为了匹配15.20,下面的工作:(\d+\.\d+)
,但是如何将否定与其他regexp字符串组合?以下操作将不起作用:(\d+.\d+)[^\w(ä196;ü220;öÖ223;è)]
?还有:我如何处理网址?类似这样的东西
$result = preg_split('/\W*\s+/', $string, NULL, PREG_SPLIT_NO_EMPTY);
,结果:
array(10) {
[0]=>
string(6) "20,000"
[1]=>
string(5) "15.20"
[2]=>
string(4) "This"
[3]=>
string(2) "is"
[4]=>
string(2) "at"
[5]=>
string(4) "Text"
[6]=>
string(5) "Right"
[7]=>
string(14) "www.google.com"
[8]=>
string(4) "Jean"
[9]=>
string(7) "Béraud"
}
问:在我的例子中,为什么\w
与匹配
答:这基于使用PCRE库的本地系统,来自:
“word”字符是任何字母、数字或下划线字符,即可以是Perl“word”的一部分的任何字符。字母和数字的定义由PCRE的字符表控制,如果发生特定于语言环境的匹配,则可能会有所不同。例如,在“fr”(法语)区域设置中,某些大于128的字符代码用于重音字母,这些字符代码由\w匹配
或者,将正则表达式指定为使用UTF-8可能会有所帮助:
$result = preg_split('/\W*\s+/u', $string, NULL, PREG_SPLIT_NO_EMPTY);
确保$string
是UTF-8编码的。由于UTF-8是国际性的,因此可能不需要考虑特定的语言环境设置。试一试。根据@hakre的答案和你的例子,我认为你应该以这种方式将这两种表达结合起来:
$result = preg_split('/[^\wäÄüÜöÖßèé]*\s+[^\wäÄüÜöÖßèé]*/', $string, NULL, PREG_SPLIT_NO_EMPTY);
您的原始表达式成功地匹配了相应的字符(代码>部分)
来自@hakre的表达式补充说,这些字符可以有任意数量(甚至没有一个字符),并且后面还应该跟一个或多个空格实例(\s+
部分)
当你把这两个想法结合起来时,你会得到[^\wä196;ü220;Ö収収収]*\s+[^\wä196;収収収収収]*
不在此字符类中的任意数量的字符,后跟至少一个空白字符,然后可能后跟不在此字符类中的任意数量的字符
或
一个或多个空白字符,以及在此字符类之前或之后不在此字符类中的任意数量的字符
作为测试,我使用了这个文本示例(我假设您希望匹配法语字符):
这个正则表达式:
已编辑
/[^\wßàâäèéêëîïôöœùûüÿç]*(^|$|\s+)[^\wßàâäèéêëîïôöœùûüÿç]*/i
通过@hakre使用的同一站点:
结束编辑
该测试表明,即使单词以其中一个特殊字符开头或结尾,表达式也会分裂。我在表达式末尾添加了/I
开关,以使匹配不区分大小写。空格拆分对您不起作用吗?不,因为我还需要将“Text.”拆分为“Text”。spliiting und spaces将忽略!?:,;理论上,这项工作是有效的,但在我的服务器配置上不是,因为外来字母将匹配为\W:-(-我将再次调查此问题…这听起来像是提供pcre库的系统上的区域设置问题。您可能需要使用mb_字符串
扩展名中的一些正则表达式函数和/或正确检查编码/字符集。看起来,preg_拆分
在mb_字符串
世界中不存在另一方面:您正在使用preg_split,但没有使用mb*
命令,并且得到了正确的结果。您是如何做到的?@TheBndr:我已经对答案添加了解释,可能还有另一个修复方法,请尝试。谢谢-我已经研究了那些mb*东西,并发现$string
不是UTF-8mb∗check_编码($string,'UTF-8')
。因此,我使用$string=mb_convert_编码($string,'UTF-8')将$string
更改为UTF-8;
现在,'/\W*\s+/u'
工作得非常好。:-)非常感谢!!现在我尝试将您的rexexp更改为在单词开头或结尾拆分,
,在“开始”或“结束”拆分:“这里”
“这里”
一个开始”
(没有开始-结束”
)谢谢你的回答!/i
是一个非常有用的提示。>我想你想匹配法语字符<不仅仅是法语。在中,有来自世界各地不同姓名的不同短信。当然,这些姓名有国家字符,如贝劳、穆勒等。使用你的链接()我注意到在Béraud?
的末尾没有拆分,以便在没有?
的情况下获得Béraud
。另一方面,它适用于对吧!
?我更正了答案中的表达式(并添加了一个新链接),因此它也适用于字符串的开头和结尾(并忽略任何开头或结尾标点)-如果您想匹配多个法语字符,请将它们添加到每个字符类中。您可以使用一个表达式来匹配您能想到的所有特殊字符,也可以使用每种语言。根据您使用的位置,可能有更好的方法来解析字符串-例如,如果字符串包含$20000,您将获得20000,不知道是美元、英镑还是里拉如果你想保留货币符号,你可以将它们添加到相应的字符类中。谢谢你的更新。我会记住这个解决方案,以备将来使用。特别是如果“\w”
/[^\wßàâäèéêëîïôöœùûüÿç]*(^|$|\s+)[^\wßàâäèéêëîïôöœùûüÿç]*/i