【问题标题】:remove content between parentheses using python regex使用 python regex 删除括号之间的内容
【发布时间】:2018-04-19 08:12:50
【问题描述】:

我有一个文本文件,例如 -

{[a] abc (b(c)d)}

我想删除这些括号 [] and (()) 之间的内容。所以输出应该是 -

 abc

我删除了括号之间的内容,但无法删除 [] 之间的内容 我试过下面的代码-

import re

with open('data.txt') as f:
    input = f.read()
    line = input.replace("{","")
    line = line.replace("}","")
    output = re.sub(r'\(.*\)', "", line)
    print output

输出是 -

[a] abc

在我的代码中,我首先替换 {},然后从 () 中删除内容。我想在output = re.sub(r'\(.*\)', "", line) 这一行中添加\[.*\]。但找不到这样做的方法。我还在学习python。所以我面临这个问题。请帮忙。

【问题讨论】:

  • 你做了\(.*\)。你也可以\[.*\]
  • 只是一个与此没有直接关系的评论:python 正则表达式并不擅长处理 balanced 括号表达式...
  • @khelwood 我已经编辑了我的问题。
  • @Jan:我知道,但是 AFAIK 标准库只包含旧的 re 模块,而 OP 有一个 import re 行...
  • 你所有的替换都可以缩短为re.sub(r'[{}]|\(.*\)|\[.*\]', "", line)

标签: python regex


【解决方案1】:

Imo 不像最初看起来那么容易,您很可能需要一些平衡(递归)方法,这可以通过 newer regex module 实现:

import regex as re

string = "some lorem ipsum {[a] abc (b(c)d)} some other lorem ipsum {defg}"

rx_part = re.compile(r'{(.*?)}')
rx_nested_parentheses = re.compile(r'\((?:[^()]*|(?R))*\)')
rx_nested_brackets = re.compile(r'\[(?:[^\[\]]*|(?R))*\]')

for match in rx_part.finditer(string):
    part = rx_nested_brackets.sub('', 
        rx_nested_parentheses.sub('', 
            match.group(1))).strip()
    print(part)

这会产生

abc
defg


模式是
\(         # opening parenthesis
(?:        # non.capturing group
    [^()]* # not ( nor )
    |      # or
    (?R)   # repeat the pattern
)*
\)

【讨论】:

  • 您的回答确实正确且内容丰富。我只是想知道这里是否需要它。 OP没有说不平衡的表情应该怎么做。 +1 递归正则表达式示例...
  • @SergeBallesta:谢谢,让我们拭目以待,看看 OP 真正想要什么。
  • @Jan 谢谢:D
【解决方案2】:

您可以检查字符串是否包含[](<no_parentheses_here>)[no_brackets_here] 子字符串,并在匹配时将其删除。

import re                                    # Use standard re
s='{[a] abc (b(c)d)}'
rx = re.compile(r'\([^()]*\)|\[[^][]*]|[{}]')
while rx.search(s):                          # While regex matches the string
    s = rx.sub('', s)                        # Remove the matches
print(s.strip())                             # Strip whitespace and show the result
# => abc

Python demo

它也适用于成对的嵌套 (...)[...]

模式详情

  • \([^()]*\) - (,然后是除 () 之外的任何 0+ 个字符,然后是 )
  • | - 或
  • \[[^][]*] - [,然后是除 [] 之外的任何 0+ 个字符,然后是 ]
  • | - 或
  • [{}] - 匹配 {} 的字符类。

【讨论】:

  • 感谢您的解释 :) @Wiktor Stribiżew
  • @jahan 如果您在模式前加上 \s*: re.compile(r'\s*(?:\([^()]*\)|\[[^][]*]|[{}])'),您也可以减少空格
  • 我还有一个问题。在我的文本文件中,第一行是 [abcdef],第二行是 {[a] abc (b(c)d)} 。所以当我使用这个正则表达式时,它会删除第一行并在第一行留出一个空白区域。输出类似于第一行 - 1. 和第二行 2. abc。我使用了 strip() 和 lsrtip() 但无法删除在第一行创建的空格。我怎么解决这个问题? @WiktorStribiżew
  • @jahan 你能创建一个代码演示吗?我不太确定我明白你的意思。如果您将文件中的内容读入字符串,那应该不是问题。如果 strip 不起作用,那可能根本不是空格,而是一些 LTR 或 RTL 标记,或其他奇怪的 Unicode 字符。另外,试试re.sub(r'^\W+|\W+$', '', s)
【解决方案3】:

我试过了,我得到了你想要的输出......我希望我没听错

import re

with open('aa.txt') as f:
    input = f.read()
    line = input.replace("{","")
    line = line.replace("}","")
    output = re.sub(r'\[.*\]', "", line)
    output = re.sub(r'\(.*\)', "", output)
    print(output)

【讨论】:

    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 2021-01-08
    • 2016-12-08
    • 2021-12-02
    相关资源
    最近更新 更多