【问题标题】:Parsing String by regular expression in python在python中通过正则表达式解析字符串
【发布时间】:2018-08-26 08:40:45
【问题描述】:

如何在 python 中解析这个字符串?

输入字符串:

someplace 2018:6:18:0 25.0114 95.2818 2.71164 66.8962 Entire grid contents are set to missing data

到这里

输出数组:

['someplace','2018:6:18:0','25.0114','95.2818','2.71164','66.8962','Entire grid contents are set to missing data']

我已经尝试过split(' '),但由于不清楚子字符串之间有多少空格,并且在最后一个子字符串内可能有空格,所以这不起作用。

我需要正则表达式。

【问题讨论】:

  • 当你只给出一个输入和输出的例子时,很难知道你想要什么正则表达式,这取决于你的数据有多一致,你可以用一些简单的字符串操作来做这种拆分,或者你可以需要复杂的正则表达式,如果没有你的所有数据(或至少有代表性的例子)就很难知道
  • 你能给我们一个解释如何分割字符串的规则吗?例如,“匹配任何内容(第 1 组),直到第一个仅由数字和冒号组成的子字符串(第 2 组),然后是四个十进制数字(数字和句点,第 3-6 组),然后是字符串的其余部分(第 7 组) )"
  • 使用 split() 代替 split('\')。它将单词之间的更多空格视为一个,并且您可以限制切割的数量:split(maxsplit=6)。
  • 我只需要可以在 split() 方法中使用的正则表达式。规则是......分隔子字符串之间和最后一个子字符串内部的空格。根据子字符串之间的空格生成数组,除了最后一个子字符串......空格数未定义

标签: python regex python-3.x python-2.7


【解决方案1】:

如果您不提供 sep-字符,pythons split(sep=None, maxsplit=-1) (doku) 会将连续的空格视为一个空格并由这些空格分隔。您可以通过提供 maxsplit 值来限制要完成的拆分数量:

data = "someplace 2018:6:18:0 25.0114  95.2818  2.71164  66.8962    Entire grid contents are set to missing data"

spl = data.split(None,6) # dont give a split-char, use 6 splits at most
print(spl)

输出:

['someplace', '2018:6:18:0', '25.0114', '95.2818', '2.71164', 
 '66.8962', 'Entire grid contents are set to missing data']

只要第一个文本不包含任何空格,这将起作用。


如果第一个文本可能包含空格,您可以使用/优化此正则表达式解决方案:

import re

reg = re.findall(r"([^\d]+?) +?([\d:]+) +?([\d.]+) +?([\d.]+) +?([\d.]+) +?([\d.]+) +(.*)$",data)[0]
print(reg)

输出:

('someplace', '2018:6:18:0', '25.0114', '95.2818', '2.71164', '66.8962', 'Entire grid contents are set to missing data')

使用 f.e.https://regex101.com 对照您的其他数据检查/证明正则表达式(点击链接,它在示例数据上使用上述正则表达式)

【讨论】:

    【解决方案2】:

    [A-Z]{1}[a-zA-Z]{15,45}|[\w|:|.]+

    你可以在这里测试https://pythex.org/

    根据需要修改 15,45。

    【讨论】:

    • 谢谢,帕特里克,你是对的。我没有运行并看到 python 代码。我已经修改了答案,现在应该没问题了。
    • 小心[A-z],它匹配Za之间的字符,即。左左括号,反斜杠,右右括号,插入符号 cirumflex,下划线,反引号。见table-ascii.com
    • 查看建议的正则表达式的[\w|:|.] 部分。 | 两个字符都不需要。另一句话:而不是[a-zA-Z ] 只使用[A-Z ] 但带有 IGNORECASE 选项。
    【解决方案3】:

    Maxsplit 也适用于 re.split():

    import re
    
    re.split(r"\s+",text,maxsplit=6)
    Out: 
    ['someplace',
     '2018:6:18:0',
     '25.0114',
     '95.2818',
     '2.71164',
     '66.8962',
     'Entire grid contents are set to missing data']
    

    编辑: 如果第一个和最后一个文本部分不包含数字,我们不需要 maxsplit 并且不必依赖连续空格的部分数量:

    re.split("\s+(?=\d)|(?<=\d)\s+",s)
    

    我们使用lookahead 和lookbehind 剪切空格后跟数字的字符串,反之亦然。

    【讨论】:

      【解决方案4】:

      由于要求不是很精确,因此很难回答您的问题。我想我会用 split() 函数分割线,然后当它们的内容没有数字时加入项目。这是一个适用于您的孤独样本的 sn-p:

      def containsNumbers(s):
          return any(c.isdigit() for c in s)
      
      data = "someplace 2018:6:18:0 25.0114  95.2818  2.71164  66.8962    Entire grid contents are set to missing data"
      lst = data.split()
      lst2 = []
      i = 0
      agg = ''
      while i < len(lst):
          if containsNumbers(lst[i]):
              if agg != '':
                  lst2.append(agg)
                  agg = ''
              lst2.append(lst[i])
          else:
              agg += ' '+lst[i]
              agg = agg.strip()
              if i == len(lst) - 1:
                  lst2.append(agg)
          i += 1
      
      print(lst2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-29
        • 2012-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多