正規表現で一般的なケースを解決することはできません。正規表現は、括弧や任意の深さでネストされた XML タグなど、スタックに類似したものを表すほど強力ではありません。
Pythonで問題を解決している場合は、次のようなことができます
import re
def roundup_sub(m):
close_paren_index = None
level = 1
for i, c in enumerate(m.group(1)):
if c == ')':
level -= 1
if level == 0:
close_paren_index = i
break
if c == '(':
level += 1
if close_paren_index is None:
raise ValueError("Unclosed roundUp()")
return 'math.ceil((' + m.group(1)[1:close_paren_index] + ')*100)/100.0' + \
m.group(1)[close_paren_index:] # matching ')' and everything after
def replace_every_roundup(text):
while True:
new_text = re.sub(r'(?ms)roundUp\((.*)', roundup_sub, text)
if new_text == text:
return text
text = new_text
これは、re.sub の repl=function 形式を使用し、正規表現を使用して先頭を見つけ、python を使用して括弧を一致させ、置換を終了する場所を決定します。
それらの使用例:
my_text = """[[[ roundUp( 10.0 ) ]]]
[[[ roundUp( 10.0 + 2.0 ) ]]]
[[[ roundUp( (10.0 * 2.0) + 2.0 ) ]]]
[[[ 10.0 + roundUp( (10.0 * 2.0) + 2.0 ) ]]]
[[[ 10.0 + roundUp( (10.0 * 2.0) + 2.0 ) + 20.0 ]]]"""
print replace_every_roundup(my_text)
出力が得られます
[[[ math.ceil((10.0 )*100)/100.0) ]]]
[[[ math.ceil((10.0 + 2.0 )*100)/100.0) ]]]
[[[ math.ceil(((10.0 * 2.0) + 2.0 )*100)/100.0) ]]]
[[[ 10.0 + math.ceil(((10.0 * 2.0) + 2.0 )*100)/100.0) ]]]
[[[ 10.0 + math.ceil(((10.0 * 2.0) + 2.0 )*100)/100.0) + 20.0 ]]]
別のオプションは、ネストされた括弧の特定の深さまで処理する正規表現を実装することです。