python正则表达式拆分任何\ W +有一些例外

时间:2013-10-18 20:34:42

标签: python regex string unicode split

使用非字母字符的正则表达式轻松分割文本:

tokens=re.split(r'(?u)\W+',text) #to split at any non-alpha unicode character

This answer提供了一种分割特定字符的方法。但是,我需要的是:

  1. 拆分任何unicode non-alpha
  2. 给正则表达式以下例外:

    • 强调“_”
    • 这条斜线“/”
    • &符“&”并在标志“@”
    • 由数字\ d +
    • 包围的fullstops
    • fullstops前面是某些任意字符串“Mr.”,“Dr。”...... etc
  3. 我可以使用正则表达式轻松地检测到这些,但问题是如何告诉正则表达式将它们作为非alpha分裂的例外。


    编辑: 这是我想要匹配的示例文本:

    text="Mr. Jones email jones@gmail.com 12.455 12,254.25 says This is@a&test example_cool man+right more/fun 43.35. And so we stopped. And then we started again. وبعدها رجعنا إلى المنزل، وقابلنا أصدقاءنا؛ وشربنا الشاي."
    

    这是它在unicode中的版本(请注意阿拉伯语中的非字母字符u'\ u060c',u'\ u061b')

    unicode_text=u'Mr. Jones email jones@gmail.com 12.455 12,254.25 says This is@a&test example_cool man+right more/fun 43.35. And so we stopped. And then we started again. \u0648\u0628\u0639\u062f\u0647\u0627 \u0631\u062c\u0639\u0646\u0627 \u0625\u0644\u0649 \u0627\u0644\u0645\u0646\u0632\u0644\u060c \u0648\u0642\u0627\u0628\u0644\u0646\u0627 \u0623\u0635\u062f\u0642\u0627\u0621\u0646\u0627\u061b \u0648\u0634\u0631\u0628\u0646\u0627 \u0627\u0644\u0634\u0627\u064a.'
    

    以下是所提供答案中正则表达式的结果:

    re.split(r'(?u)(?![\+&\/@\d+\.\d+Mr\.])\W+',unicode_text)
    
      

    [u'Mr。',u'Jones',u'email',u'jones @ gmail.com',u'12.455',u'12',   u'254.25',u'says',u'This',u'is @ a& test',u'example_cool',   u'man + right',u'more / fun',u'43.35。',u'And',u'so',u'we',   你停止了。','你','你','我们',你开始','我们'。',   U '\ u0648 \ u0628 \ u0639 \ u062f \ u0647 \ u0627',   你'u u u u u'''''''''''''''''''''''''''''''''''''''''''''''''''   U '\ u0627 \ u0644 \ u0645 \ u0646 \ u0632 \ u0644',   U '\ u0648 \ u0642 \ u0627 \ u0628 \ u0644 \ u0646 \ u0627',   U '\ u0623 \ u0635 \ u062f \ u0642 \ u0627 \ u0621 \ u0646 \ u0627',   U '\ u0648 \ u0634 \ u0631 \ u0628 \ u0646 \ u0627',   的u '\ u0627 \ u0644 \ u0634 \ u0627 \ u064a。']

    请注意,正则表达式没有在单词结尾处的fullstops周围分割。所以有一些东西可以处理这个

2 个答案:

答案 0 :(得分:0)

关键是使用否定前瞻。我认为这涵盖了您列表中的所有示例,但请告诉我是否遗漏了一些内容。

In [549]: re.split(r'(?u)(?![\+&\/@\d+\.\d+Mr\.])\W+', "Mr.Jones says This is@a&test example_cool man+right more/fun 43.35")
Out[549]: ['Mr.Jones', 'says', 'This', 'is@a&test', 'example_cool', 'man+right', 'more/fun', '43.35']

(?!)组内的任何内容都不会匹配。如果我正确理解了这个问题,请告诉我。

答案 1 :(得分:0)

我认为您不想在jones@gmail.comjones@gmail中拆分com之类的电子邮件地址,因此我更改了您的例外要求数字包围的全站点句号后跟一个字母数字字符

re.split(r'(?u)(?![_/&@.])\W+|(?<!Mr|Dr)\.(?!\w)\W*', unicode_text)
  

[u'Mr。',u'Jones',u'email',u'jones @ gmail.com',u'12.455',u'12',   u'254.25',u'says',u'This',u'is @ a&amp; test',u'example_cool',u'man',   u'right',u'more / fun',u'43.35',u'And',u'so',u'we',u'stopped',   你和','你','你'开始','你','   U '\ u0648 \ u0628 \ u0639 \ u062f \ u0647 \ u0627',   你'u u u u u'''''''''''''''''''''''''''''''''''''''''''''''''''   U '\ u0627 \ u0644 \ u0645 \ u0646 \ u0632 \ u0644',   U '\ u0648 \ u0642 \ u0627 \ u0628 \ u0644 \ u0646 \ u0627',   U '\ u0623 \ u0635 \ u062f \ u0642 \ u0627 \ u0621 \ u0646 \ u0627',   U '\ u0648 \ u0634 \ u0631 \ u0628 \ u0646 \ u0627',   你'u u u u u u'''''''''''