【问题标题】:Split Python String by letters and keep deliminators按字母拆分 Python 字符串并保留分隔符
【发布时间】:2019-11-04 18:24:03
【问题描述】:

使用正则表达式,我如何拆分字符串并在返回的结果中保留它的分隔符?我正在尝试将包含数字和字符串的字符串拆分为一组字母,后跟任何数值,包括“。”但是它似乎无法正常工作。

下面是我的测试字符串,我使用的是 python 2.7,它没有产生预期的 id。

s = 'M160.394,83.962L121.5,52L86.31,73.378L58,104.917L89.75,C136.667L158.542,136.667L185,110.208L160.394,83.962Z'
parts = filter(None, re.split('([MLHVCSQTAZ][^MLHVCSQTAZ]+)', s, re.IGNORECASE))
print len(parts), parts
>>> 3 ['M160.394,83.962', 'L121.5,52', 'L86.31,73.378L58,104.917L89.75,C136.667L158.542,136.667L185,110.208L160.394,83.962Z']

我希望它能给我这个

>>> 10 ['M160.394,83.962', 'L121.5,52', 'L86.31,73.378', 'L58,104.917', 'L89.75,', 'C136.667', 'L158.542,136.667', 'L185,110.208', 'L160.394,83.962', 'Z']

它应该输出一个字符串列表,其中每个字符串都以一个字母开头,在原始正则表达式MLHVCSQTAZ中找到

【问题讨论】:

  • 您可以使用findall 或拆分(?<!^)(?=[MLHVCSQTAZ][^MLHVCSQTAZ]+)

标签: python regex


【解决方案1】:

在您的代码中,您将 re.IGNORECASE 作为第三个参数传递给 re.split3rd argument of re.split is maxsplit not flags.

re.IGNORECASE 等于 2,因此您的输入仅被拆分两次。

您可以使用:

>>> list(filter(None, re.split(r'([MLHVCSQTAZ][^MLHVCSQTAZ]+)', s, 0, re.I)))
['M160.394,83.962', 'L121.5,52', 'L86.31,73.378', 'L58,104.917', 'L89.75,', 'C136.667', 'L158.542,136.667', 'L185,110.208', 'L160.394,83.962', 'Z']

或者使用内联模式忽略大小写:

re.split(r'(?i)([MLHVCSQTAZ][^MLHVCSQTAZ]+)', s)

我建议使用这个简单的re.findall 代码,它使用几乎相同的正则表达式:

parts = re.findall('(?i)[MLHVCSQTAZ][^MLHVCSQTAZ]*', s)

参考: SRE_FLAG_IGNORECASE = 2 in lib/python2.7/sre_constants.py(感谢@vks 的评论)

【讨论】:

  • re.IGNORECASE equals to 2 hence your input is split only two times.哈哈很好找!!!可能还提到了来源....SRE_FLAG_IGNORECASE = 2 in lib/python2.7/sre_constants.py
  • 谢谢@vks。我已添加此来源参考。
【解决方案2】:

你可以使用re.findall:

import re
s = 'M160.394,83.962L121.5,52L86.31,73.378L58,104.917L89.75,C136.667L158.542,136.667L185,110.208L160.394,83.962Z'
result = re.findall('[A-Z][\.\d,]+|[A-Z]', s)

输出:

['M160.394,83.962', 'L121.5,52', 'L86.31,73.378', 'L58,104.917', 'L89.75,', 'C136.667', 'L158.542,136.667', 'L185,110.208', 'L160.394,83.962', 'Z']

【讨论】:

    【解决方案3】:
    parts = filter(None, re.split('([MLHVCSQTAZ][^MLHVCSQTAZ]+)', s, flags=re.IGNORECASE))
    

    您需要使用flags。检查re.split函数定义。

    默认re不支持0 width assertion split。所以你也可以使用regex模块。

    import regex
    s = 'M160.394,83.962L121.5,52L86.31,73.378L58,104.917L89.75,C136.667L158.542,136.667L185,110.208L160.394,83.962Z'
    print regex.split('(?=[MLHVCSQTAZ][^MLHVCSQTAZ])', s, flags=regex.IGNORECASE|regex.VERSION1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-26
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 2011-01-09
      相关资源
      最近更新 更多