Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 仅拆分特殊字符上的文本,但不拆分带小数点的数字_Php_Regex - Fatal编程技术网

Php 仅拆分特殊字符上的文本,但不拆分带小数点的数字

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

我正在考虑PHP中一个特殊的regexp问题,但我找不到解决方案。 我尝试将一些文本拆分为术语,以获得简单的单词、数字和网址

所以我决定对每个非字母数字字符(\w)进行拆分

为了使用不同的语言,我将\w与其他字母一起使用,如Ääè等

例如:

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-8
mb∗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