在 eval() 中使用 Python 正则表达式匹配
Using Python regex matches in eval()
我想利用用户输入来匹配和重新排列字符串。
在 Perl 中,一个简单的示例如下所示:
use strict;
my $str = 'abc123def456ghi';
my $user_input1 = '(\d+).+?(\d+)';
my $user_input2 = '.';
if ($str =~ /$user_input1/) {
my $newstr = eval($user_input2);
print $newstr;
}
else {print "No match..."};
原则上同样适用于 Python:
import re
mystr = 'abc123def456ghi'
user_input1 = '(\d+).+?(\d+)'
user_input2 = 'm.group(2) + m.group(1)'
m = re.search(user_input1,mystr)
if m:
newstr = eval(user_input2)
print (newstr)
else: print ("No match...")
结果:456123
但是,如果您必须在输入字段中多次键入表达式 'm.group(1)'
和 'm.group(2)'
,则表达式不是很友好。
因此,我想知道在Python中是否有类似于Perl中的''
''
的紧凑表达式?
我无法在 Python 和 ''
和 ''
中使用它。
有什么想法吗?
编辑:
对不起,我试着在下面的一些评论后解释:
我正在尝试 eval()
因为它似乎可以与 m.group(1)
等一起使用。
但显然由于某种原因 r''
等在 eval()
中不被接受
import re
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r''
newstr = eval(user_input2)
print (newstr)
结果
SyntaxError: unexpected character after line continuation character
关于使用re.sub()
的建议
应该不是简单的字符串替换,而是重排+匹配。
如果我修改原始正则表达式
user_input1 = r'(.+?)(\d+).+?(\d+)(.+)'
我可以用user_input2 = r''
然而,例如如果我想在匹配之间添加“999”(当然,r'99'
或 r'+"999"+'
都不会这样做)那么我可能会回来使用 eval()
和 m.group(1)
等。虽然我想让用户输入尽可能简短。也许,我可以使用一些建议的替代品。
"inspired" 由上面的评论,我觉得下面的好像是我问题的答案。 (假设您只有 </code> 到 <code>
)。至少,这个解决方案对我来说并不直观和明显(正如 Python 喜欢的那样)。欢迎使用更优雅的结构。
import re
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r'+"999"+'
user_input2 = re.sub(r'\(\d)',r'm.group()',user_input2,flags=re.S)
m = re.search(user_input1,mystr)
if m:
newstr = eval(user_input2)
print (newstr)
您不需要 eval
。事实上,you want to avoid eval
like the plague.
您可以使用 match.expand
获得相同的输出:
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r''
match = re.search(user_input1, mystr)
result = match.expand(user_input2)
# result: 456123
关于在匹配项之间插入 999
的示例可以使用 \g<group_number>
语法轻松解决:
mystr = 'abc123def456ghi'
user_input1 = r'(.+?)(\d+).+?(\d+)(.+)'
user_input2 = r'\g<3>999'
match = re.search(user_input1, mystr)
result = match.expand(user_input2)
# result: 456999123
如您所见,如果您需要做的只是四处移动捕获的文本并插入新文本,则正则表达式模块可以满足您的需求。仅当您 确实 必须执行代码时才使用 eval
。
我想利用用户输入来匹配和重新排列字符串。 在 Perl 中,一个简单的示例如下所示:
use strict;
my $str = 'abc123def456ghi';
my $user_input1 = '(\d+).+?(\d+)';
my $user_input2 = '.';
if ($str =~ /$user_input1/) {
my $newstr = eval($user_input2);
print $newstr;
}
else {print "No match..."};
原则上同样适用于 Python:
import re
mystr = 'abc123def456ghi'
user_input1 = '(\d+).+?(\d+)'
user_input2 = 'm.group(2) + m.group(1)'
m = re.search(user_input1,mystr)
if m:
newstr = eval(user_input2)
print (newstr)
else: print ("No match...")
结果:456123
但是,如果您必须在输入字段中多次键入表达式 'm.group(1)'
和 'm.group(2)'
,则表达式不是很友好。
因此,我想知道在Python中是否有类似于Perl中的''
''
的紧凑表达式?
我无法在 Python 和 ''
和 ''
中使用它。
有什么想法吗?
编辑:
对不起,我试着在下面的一些评论后解释:
我正在尝试 eval()
因为它似乎可以与 m.group(1)
等一起使用。
但显然由于某种原因 r''
等在 eval()
import re
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r''
newstr = eval(user_input2)
print (newstr)
结果
SyntaxError: unexpected character after line continuation character
关于使用re.sub()
的建议应该不是简单的字符串替换,而是重排+匹配。 如果我修改原始正则表达式
user_input1 = r'(.+?)(\d+).+?(\d+)(.+)'
我可以用user_input2 = r''
然而,例如如果我想在匹配之间添加“999”(当然,r'99'
或 r'+"999"+'
都不会这样做)那么我可能会回来使用 eval()
和 m.group(1)
等。虽然我想让用户输入尽可能简短。也许,我可以使用一些建议的替代品。
"inspired" 由上面的评论,我觉得下面的好像是我问题的答案。 (假设您只有 </code> 到 <code>
)。至少,这个解决方案对我来说并不直观和明显(正如 Python 喜欢的那样)。欢迎使用更优雅的结构。
import re
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r'+"999"+'
user_input2 = re.sub(r'\(\d)',r'm.group()',user_input2,flags=re.S)
m = re.search(user_input1,mystr)
if m:
newstr = eval(user_input2)
print (newstr)
您不需要 eval
。事实上,you want to avoid eval
like the plague.
您可以使用 match.expand
获得相同的输出:
mystr = 'abc123def456ghi'
user_input1 = r'(\d+).+?(\d+)'
user_input2 = r''
match = re.search(user_input1, mystr)
result = match.expand(user_input2)
# result: 456123
关于在匹配项之间插入 999
的示例可以使用 \g<group_number>
语法轻松解决:
mystr = 'abc123def456ghi'
user_input1 = r'(.+?)(\d+).+?(\d+)(.+)'
user_input2 = r'\g<3>999'
match = re.search(user_input1, mystr)
result = match.expand(user_input2)
# result: 456999123
如您所见,如果您需要做的只是四处移动捕获的文本并插入新文本,则正则表达式模块可以满足您的需求。仅当您 确实 必须执行代码时才使用 eval
。