【问题标题】:Regex substitution between two expressions两个表达式之间的正则表达式替换
【发布时间】:2020-08-02 08:47:00
【问题描述】:

假设我有以下字符串:

stringX = ['187-49481,14',
'181-457216',
'196,61-04-22',
'1972-10-28',
'19,940-04-16',
'2017-08,8-29',
'2014-04-18']

请注意,我有两种类型的字符串:类型 181-457216 和类型 1972-10-28(日期) 我正在修改 CSV,由于某种原因(仔细查找,没有找到任何原因),它有时 - 显然是随机地 - 在这些类型的字符串中的数字之间插入逗号。

所以我想要完成的是通过正则表达式检测这些逗号并将它们替换为空(删除逗号)。

说第一种类型的字符串,即:'187-14,412' 我一直在尝试:

re.sub(r'\d+\-\d+(\,)\d+', '', stringX)

在这个例子中,逗号是第 1 组,但我如何在这个正则表达式中指定子组(1)?

我也一直在尝试lookbehind和lookahead,但是lookbehind有问题:

(?<=\d+\-\d+)(\,)(?=\d+)
Err: lookbehind assertion is not fixed length at offset 0

如果有更好的方法来正则表达式这些字符串,或者能够在 re.sub 上指定 group(1),我正在徘徊

【问题讨论】:

  • 我的建议是仔细研究为什么修改 CSV 文件的代码会产生错误(也许在这里发布一个问题)。试图解决错误(尤其是当它们出现在您自己的代码中时)是一种愚蠢的游戏。但是,要删除逗号,为什么不将它们转换为空字符串。为此,您甚至不需要正则表达式。
  • 似乎除了逗号之外修改 CSV 文件的代码还会在数据条目中插入一个额外的数字。 187-49481,14 应该是 187-494814, 196,61-04-22 -> 1961-04-22 等等。

标签: python regex


【解决方案1】:

你不需要正则表达式,你可以在','处分割字符串。如果它产生一个长度大于 1 的数组,则砍掉左字符串的最后一个索引(在索引 0 处)和右字符串的第一个索引(在索引 1 处)。 哦,也许你确实需要它,idk。

const p = '187-49481,14';
const regex = /\d,/;
console.log(p.replace(regex, ''));//result is 187-494814

这是在 JavaScript 中完成的,但应该与 Python 匹配 \d, 一样简单,并将其替换为空。十分简单, 我不太了解 Python,但可能会这样做

re.sub(r'\d,', '', stringX)

【讨论】:

    【解决方案2】:
    import re
    [re.sub(r'\,', '', x) for x in stringX]
    
    ['187-4948114', '181-457216', '19661-04-22', '1972-10-28', '19940-04-16', '2017-088-29', '2014-04-18']
    

    【讨论】:

      【解决方案3】:

      解决方案

      您可以使用简单的pythonic list-comprehensionstr.replace()

      [x.replace(',','') for x in stringX]
      

      输出

      ['187-4948114',
       '181-457216',
       '19661-04-22',
       '1972-10-28',
       '19940-04-16',
       '2017-088-29',
       '2014-04-18']
      

      如果你想使用regex,那么这可能是一个替代方案。

      import re # regex library
      re.sub(',','', '|'.join(stringX)).split('|')
      

      输出

      ['187-4948114',
       '181-457216',
       '19661-04-22',
       '1972-10-28',
       '19940-04-16',
       '2017-088-29',
       '2014-04-18']
      

      提取单虚线和双虚线值

      您可以使用re.findall() 提取带有单破折号和双破折号的数字,如下所示。

      import re # regex library
      
      text = [x.replace(',','') for x in stringX]
      text = '\n'.join(text)
      single_dash = re.findall('\d+-\d+', text)
      double_dash = re.findall('\d+-\d+-\d+', text)
      print(f'single dash: \n\n{single_dash}\n')
      print(f'double dash: \n\n{double_dash}\n')
      

      输出

      single dash: 
      
      ['187-4948114', '181-457216', '19661-04', '1972-10', '19940-04', '2017-088', '2014-04']
      
      double dash: 
      
      ['19661-04-22', '1972-10-28', '19940-04-16', '2017-088-29', '2014-04-18']
      

      【讨论】:

      • @SahiraMena 或许您还需要提取单虚线和双虚线的值,如果需要,请查看此解决方案的最后部分。
      【解决方案4】:

      您可以使用lambda expression in re.sub 来使用您的正则表达式方法

      改变

      re.sub(r'\d+\-\d+(\,)\d+', '', stringX)
      

      收件人:

      re.sub(r'\d+\-\d+(\,)\d+', lambda m: m.group(0).replace(',', ''), stringX)
      

      【讨论】:

      • 所有答案都很棒,但是这样做并学习了 re.sub 的一个很好的功能。我最终做了 re.sub(r'\d+\-\d+(\,)\d+', lambda m: re.sub(r'\,','',m.group(0)), stringX)并做了一个双重re.sub
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-24
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多