【问题标题】:Python replace all occurrences found using regexPython 替换使用正则表达式找到的所有匹配项
【发布时间】:2019-04-13 21:58:31
【问题描述】:

在python中,尝试替换使用正则表达式找到的所有字符串,例如:

'10am 11pm 13am 14pm 4am'

变成

'10 am 11 pm 13 am 14 pm 4 am'

我试过了

re.sub('([0-9].*)am(.*)', r'\1 am \2', ddata) 

但这只会替换最后一次出现。

import re
regex = re.compile('([0-9].*)am+', re.S)
myfile =  '10am 11pm 13am 14pm 4am'
myfile2 = regex.sub(lambda m: m.group().replace(r'am',r" am ",1), myfile)
print(myfile2)

只替换第一次出现的'am'

对我的预期结果'10 am 11pm 13 am 14pm 4 am'

【问题讨论】:

  • (\d{1,2})(?=[ap]m) 替换为\1 (see here) (\d{1,2})([ap]m) 替换为\1 \2(see here)
  • 我想我不清楚我在这种情况下使用的是 reg ex。想象一下这句话:“圆形剧场在上午 10 点至上午 11 点和下午 3 点至晚上 7 点开放”——我们要确保不要替换圆形剧场中的“上午”。
  • 真正的问题是你真的想改变那个句子/例子吗?鉴于您设置的条件,您 可以 使用它,但它会很丑陋。 >>> re.sub(r'(?<=\d)([ap]m)', r' \1', 'the amphitheater opens at 10am-11am and 3pm-7pm')...#OUTPUT: 'the amphitheater opens at 10 am-11 am and 3 pm-7 pm'
  • @FailSafe 得出了同样的结论。积极的后视工作,但句子看起来很难看。 OP是否想要10 am - 11 am and 3 pm - 7 pm之类的东西?现在这完全是原始帖子中的另一个问题。 :)
  • @FailSafe 这句话转换不适合人类消费,所以是的,我真的很想这样做。

标签: python regex


【解决方案1】:

对数字和“am”或“pm”字符串使用捕获组,然后用组之间的空格替换。

import re

s = '10am 11pm 13am 14pm 4am'

subbed = re.sub(r'(\d+)([ap]m)', r'\1 \2', s)
print(subbed)
# 10 am 11 pm 13 am 14 pm 4 am

【讨论】:

    【解决方案2】:

    这将完成工作:

    import re
    myfile =  '10am 11pm 13am 14pm 4am'
    re.sub(r'(\d+)(am|pm)', r'\1 \2', myfile)
    

    这是测试输出:

    >>> import re
    >>> myfile =  '10am 11pm 13am 14pm 4am'
    >>> re.sub(r'(\d+)(am|pm)', r'\1 \2', myfile)
    '10 am 11 pm 13 am 14 pm 4 am'
    >>> 
    

    编辑:这是处理您在 cmets 中发布的字符串的相同解决方案的输出:

    >>> import re
    >>> myfile = 'The amphitheater opens at 10am-11am and 3pm-7pm'
    >>> re.sub(r'(\d+)(am|pm)', r'\1 \2', myfile)
    'The amphitheater opens at 10 am-11 am and 3 pm-7 pm'
    >>> 
    

    【讨论】:

    • 我想我不清楚我在这种情况下使用的是 reg ex。想象一下这句话:“圆形剧场在上午 10 点至上午 11 点和下午 3 点至晚上 7 点开放”——我们要确保不要替换圆形剧场中的“上午”。
    • @jvence,你检查我的答案了吗?它解决了这个问题,因为我匹配数字后跟 am 或 pm,没有空格。
    【解决方案3】:

    如果你真的想要一个使用正则表达式而不是上面提到的纯字符串 replace 方法的解决方案,你可以使用下面的 sn-p。

    import re
    myfile = '10am 11pm 13am 14pm 4am'
    myfile2 = re.sub(r'(\d+)(am)', lambda m: '{} {}'.format(*m.groups()), myfile, 0)
    print(myfile2)
    

    【讨论】:

    • 既然已经在使用re.sub,为什么还要引入lambdastr.format
    • @accdias 这是必需的,因为您需要知道数字和上午/下午信息。该解决方案可以灵活地处理上午和下午信息。我最初的 sn-p 将正则表达式的第二部分作为 (am|pm),后来被编辑为仅包含 am,因为这就是 OP 所要求的。希望能回答你的问题。
    • 我明白你在这里指的是什么,而不是lambda,你可以直接使用像r'\1 \2'这样的反向引用
    【解决方案4】:

    你可以在不使用 re: 的情况下做到这一点:

    '10am 11pm 13am 14pm 4am'.replace('a',' a').replace('p',' p')  
    
    ## Output: '10 am 11 pm 13 am 14 pm 4 am'
    

    【讨论】:

    • 感谢您没有使用比所需更复杂的解决方案。讨厌说我想知道这个问题是否会被 -1'ed?无论如何,如果他想要正则表达式,我会将其发布在您的下方,因为这里根本不需要完整的答案。 >>> re.sub(r'(a|p)', r' \1', '10am 11pm 13am 14pm 4am') ...... #OUTPUT: '10 am 11 pm 13 am 14 pm 4 am'
    • @FailSafe 谢谢,您的正则表达式模式是本页其他模式中最简洁和最贴切的。希望 OP 注意到它。
    • @FailSafe 请参阅上面添加的关于以下句子的评论:“圆形剧场于上午 10 点至上午 11 点和下午 3 点至下午 7 点开放”
    • 这将产生附带影响,字符串超出该模式。
    猜你喜欢
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    相关资源
    最近更新 更多