【问题标题】:How to extract a part of the string in python?如何在python中提取字符串的一部分?
【发布时间】:2021-08-26 14:47:16
【问题描述】:

我有以下清单:

lst = ['SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 18847, NULL), NULL, NULL)', 
'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 19188, NULL), NULL, NULL)',
'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9972, 18282, NULL), NULL, NULL)',
'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9977, 19201, NULL), NULL, NULL)',
'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9989, 18635, NULL), NULL, NULL)']

我只想提取包含 MDSYS.SDO_POINT_TYPE 之后括号中数字的字符串。我该怎么做?

到目前为止我尝试了什么?

op=[]
for i in lst:
    x = (i[46:56])
    y = str('('+x+')')
    op.append(y)

但是,数字并不总是在 46-56 位,我该如何优化呢?

期望的输出:

['(9971, 1884)',
 '(9971, 1918)',
 '(9972, 1828)',
 '(9977, 1920)',
 '(9989, 1863)']

【问题讨论】:

    标签: python string list substring extract


    【解决方案1】:

    如果括号和NULL之间的数字可以在不同的位置,您可以使用模式首先获取捕获组中括号之间的值。

    然后你可以找到第 1 组值中的数字。

    \bMDSYS\.SDO_POINT_TYPE\(([^()]+)\)
    
    • \bMDSYS\.SDO_POINT_TYPE\( 匹配 MDSYS\.SDO_POINT_TYPE(
    • ([^()]+) 捕获组 1 中括号之间的所有内容
    • \) 比赛结束)

    查看Python demo 广告Regex demo

    注意,在所需的输出中,第二个值缺少最后一位。

    import re
    
    lst = ['SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 18847, NULL), NULL, NULL)',
           'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 19188, NULL), NULL, NULL)',
           'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9972, 18282, NULL), NULL, NULL)',
           'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9977, 19201, NULL), NULL, NULL)',
           'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9989, 18635, NULL), NULL, NULL)']
    
    op = []
    for s in lst:
        m = re.search(r"\bMDSYS\.SDO_POINT_TYPE\(([^()]+)\)", s)
        if m:
            op.append("({})".format(", ".join(re.findall(r"\d+", m.group(1)))))
    
    print(op)
    

    输出

    ['(9971, 18847)', '(9971, 19188)', '(9972, 18282)', '(9977, 19201)', '(9989, 18635)']
    

    【讨论】:

      【解决方案2】:

      我只是使用split 将其分解为列表并再次与字符串组合

      lst = ['SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 18847, NULL), NULL, NULL)', 
          'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9971, 19188, NULL), NULL, NULL)',
          'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9972, 18282, NULL), NULL, NULL)',
          'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9977, 19201, NULL), NULL, NULL)',
          'SDO_GEOMETRY(2001, NULL, MDSYS.SDO_POINT_TYPE(9989, 18635, NULL), NULL, NULL)']
      
      new_lst = []
      for st in lst:
        name,points = st.split('MDSYS.SDO_POINT_TYPE(')
        f_num, s_num, *rest_ = points.split(',')
        new_lst.append(f"({f_num},{s_num})")
      
      print(new_lst)
      

      【讨论】:

        【解决方案3】:

        你可以使用正则表达式:

        import re
        >>> [re.findall("MDSYS.SDO_POINT_TYPE\((\d+, \d+)", s)[0] for s in lst]
        ['9971, 18847', '9971, 19188', '9972, 18282', '9977, 19201', '9989, 18635']
        

        【讨论】:

        • 确实,但如果所需的输出包含括号,那么您的输出将需要进行后处理。用[f'({pair})' for pair in list_of_pairs] 或其他什么都相当简单。
        猜你喜欢
        • 2017-09-18
        • 1970-01-01
        • 2019-07-13
        • 2020-12-18
        • 1970-01-01
        • 2015-09-19
        • 2016-05-11
        相关资源
        最近更新 更多