我对这个问题有些困难。我需要删除波浪括号中包含的所有数据。
像这样:
Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there.
变为:
Hello there.
这是我的第一次尝试(我知道它很可怕):
while 1:
firstStartBracket = text.find('{{')
if (firstStartBracket == -1):
break;
firstEndBracket = text.find('}}')
if (firstEndBracket == -1):
break;
secondStartBracket = text.find('{{',firstStartBracket+2);
lastEndBracket = firstEndBracket;
if (secondStartBracket == -1 or secondStartBracket > firstEndBracket):
text = text[:firstStartBracket] + text[lastEndBracket+2:];
continue;
innerBrackets = 2;
position = secondStartBracket;
while innerBrackets:
print innerBrackets;
#everytime we find a next start bracket before the ending add 1 to inner brackets else remove 1
nextEndBracket = text.find('}}',position+2);
nextStartBracket = text.find('{{',position+2);
if (nextStartBracket != -1 and nextStartBracket < nextEndBracket):
innerBrackets += 1;
position = nextStartBracket;
# print text[position-2:position+4];
else:
innerBrackets -= 1;
position = nextEndBracket;
# print text[position-2:position+4];
# print nextStartBracket
# print lastEndBracket
lastEndBracket = nextEndBracket;
print 'pos',position;
text = text[:firstStartBracket] + text[lastEndBracket+2:];
它似乎工作但内存耗尽很快。有没有更好的方法来做到这一点(希望用正则表达式)?
编辑:我不清楚,所以我再举一个例子。我需要允许多个顶级括号。像这样:
Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there {{my }} friend.
变为:
Hello there friend.
答案 0 :(得分:4)
您可以在此处使用pyparsing
module。基于this answer的解决方案:
from pyparsing import nestedExpr
s = "Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there {{my }} friend."
expr = nestedExpr('{{', '}}')
result = expr.parseString("{{" + s + "}}").asList()[0]
print(" ".join(item for item in result if not isinstance(item, list)))
打印:
Hello there friend.
以下只有在只有一个顶级大括号时才有效。
如果你想用大括号本身删除双花括号里面的所有东西:
>>> import re
>>>
>>> s = "Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there."
>>> re.sub(r"\{\{.*\}\} ", "", s)
'Hello there.'
\{\{.*\}\}
会匹配双花括号,后跟任意次数的任意字符(故意留下"greedy"),然后是双花括号和空格。
答案 1 :(得分:4)
这是一个基于正则表达式/生成器的解决方案,适用于任意数量的大括号。此问题不需要实际堆栈,因为只涉及一种类型(井,对)令牌。 Autofac
填充堆栈填充更复杂的解析器的角色。
MVC 6
更一般的要点......正则表达式中的捕获组是使level
的输出中出现大括号的原因,否则你只能得到它们之间的东西。还有一些支持不匹配的括号。对于严格的解析器,应该引发异常,因为应该使用级别&gt;运行字符串的结尾。 0.对于松散的Web浏览器样式解析器,您可能希望将那些import re
def _parts_outside_braces(text):
level = 0
for part in re.split(r'(\{\{|\}\})', text):
if part == '{{':
level += 1
elif part == '}}':
level = level - 1 if level else 0
elif level == 0:
yield part
x = 'Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there. {{ second set {{ of }} braces }}'
print(''.join(_parts_outside_braces(x)))
显示为输出...
答案 2 :(得分:1)
请尝试以下代码:
import re
s = 'Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there'
m = re.search('(.*?) {.*}(.*)',s)
result = m.group(1) + m.group(2)
print(result)
答案 3 :(得分:1)
问题是您必须处理嵌套结构,这意味着正则表达式可能不够。但是,一个具有深度级别内存的简单解析器可能会被拯救 - 编写起来非常简单,只需存储即可 深度级别变为变量。
我只是在这里发布一种更加pythonic的方式来编写解决方案,这可能是一个很好的参考。
import re
def rem_bra(inp):
i = 0
lvl = 0
chars = []
while i < len(inp):
if inp[i:i+2] == '{{':
lvl += 1
i += 1
elif inp[i:i+2] == '}}':
lvl -= 1
i += 1
else:
if lvl < 1:
chars.append(inp[i])
i += 1
result = ''.join(chars)
# If you need no more contigious spaces, add this line:
result = re.sub(r'\s\s+', r' ', result)
return result
inp = "Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there."
print(rem_bra(inp))
>>> Hello there.
答案 4 :(得分:1)
为了更好的衡量,还有另一种解决方案。它首先找到并替换最左边的最内侧支撑,然后向外,向右移动。照顾多个顶级牙箍。
import re
def remove_braces(s):
pattern = r'\{\{(?:[^{]|\{[^{])*?\}\}'
while re.search(pattern, s):
s = re.sub(pattern, '', s)
return s
不是效率最高,但很短。
>>> remove_braces('Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there {{my }} friend.')
'Hello there friend.'
答案 5 :(得分:1)
这个问题很有趣。这是我的尝试:
import re
def find_str(string):
flag = 0
for index,item in enumerate(string):
if item == '{':
flag += 1
if item == '}':
flag -= 1
if flag == 0:
yield index
s = 'Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there {{my }} friend.'
index = list(find_str(s))
l = [s[i] for i in index]
s = ' '.join(l)
re.sub('}\s+','',s)
'H e l l o t h e r e f r i e n d .'
答案 6 :(得分:0)
使用Python regex package可以使用recursive regex。
{{(?>[^}{]+|(?0))*}} ?
或另一种变体(需要更多步骤)。
{{(?>[^}{]*(?R)?)*}} ?
粘贴(?0)
或(?R)
模式。与regex.sub
>>> import regex
>>> str = 'Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there.'
>>> regex.sub(r'(?V1){{(?>[^}{]+|(?0))*}} ?', '', str)
(?V1)
版本1的行为与Perl类似。无法测试,你需要尝试:)