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

时间:2011-09-28 15:44:04

标签: php regex

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

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

要使用不同的语言,我会使用\ w和其他字母,例如ÄäéèÈ等。

示例:

20,000 15.20 This is at Text. Right?!
www.google.com Jean Béraud

到目前为止,我使用以下正则表达式来分割文本:

[^\w(äÄüÜöÖßèé)]

http://regexr.com?2uq98

在80%的案例中效果很好,但将20,000分为20和000也将www.google.com分成www google com

所以我试着将这些数字保持在一起,但仍然分为点数,例如Text.以获得Text

要匹配15.20,以下工作:(\d+\.\d+),但如何将否定与其他正则表达式字符串组合?以下操作无效:(\d+\.\d+)|[^\w(äÄüÜöÖßèé)]
并且:我如何处理网址?

2 个答案:

答案 0 :(得分:2)

这样的东西?

$result = preg_split('/\W*\s+/', $string, NULL, PREG_SPLIT_NO_EMPTY);

Demo,结果:

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库的系统的本地,来自PHP Manual

  

“单词”字符是任何字母或数字或下划线字符,即任何可以成为Perl“单词”一部分的字符。字母和数字的定义由PCRE的字符表控制,如果发生特定于语言环境的匹配,则可能会有所不同。例如,在“fr”(法语)语言环境中,一些大于128的字符代码用于重音字母,并且这些字符代码由\ w匹配。

或者,将正则表达式指定为使用UTF-8可能会有所帮助:

$result = preg_split('/\W*\s+/u', $string, NULL, PREG_SPLIT_NO_EMPTY);

确保$string采用UTF-8编码。由于UTF-8是国际的,因此可能不需要考虑特定的区域设置。试一试。

答案 1 :(得分:1)

根据@hakre的回答和你的例子,我相信你应该用这种方式组合这两个表达式:

$result = preg_split('/[^\wäÄüÜöÖßèé]*\s+[^\wäÄüÜöÖßèé]*/', $string, NULL, PREG_SPLIT_NO_EMPTY);

您的原始表达式已成功匹配相应的字符([^\w(äÄüÜöÖßèé)]部分)。

来自@hakre的表达式补充说,这些字符中可能有任意一个字符(甚至没有字符),并且还应该跟一个或多个空格实例(\s+部分)。

当你将这两个想法结合起来时,你会得到[^\wäÄüÜöÖßèé]*\s+[^\wäÄüÜöÖßèé]*,这基本上转化为

  

此字符类中没有的任意数量的字符,后跟至少一个空格字符,然后可能后跟任何不在此字符类中的字符

  

之前或之后的一个或多个空白字符,以及不在此字符类中的任意数量的字符

作为测试,我使用了这个文本示例(我假设你想匹配法语字符):

20,000 15.20 This is at Text. Right?!
www.google.com Comme son élève, où dois-je aller voir Jean Béraud?

和这个正则表达式: 的 EDITED

/[^\wßàâäèéêëîïôöœùûüÿç]*(^|$|\s+)[^\wßàâäèéêëîïôöœùûüÿç]*/i

通过@hakre使用的同一网站:

http://codepad.viper-7.com/MqztVt

结束编辑

此测试显示即使单词以其中一个特殊字符开头或结尾,表达式也会分裂。我在表达式的末尾添加了/i开关,以使匹配不区分大小写。