在用户提交的正则表达式中查找捕获组
Find capturing groups in user submitted regex
我有一个 python 应用程序需要处理用户提交的正则表达式。
由于性能方面的考虑,我想禁止捕获组和反向引用。
我的想法是使用另一个正则表达式来验证用户提交的正则表达式不包含任何命名或未命名的组捕获,如下所示:
def validate_user_regex(pattern):
if re.match('[^\\]\((?:\?P).*?[^\\]\)', pattern) is not None:
return False
return True
虽然我认为我的想法可能适用于捕获组,但我不确定这是否会阻止各种反向引用。
那么有没有更聪明的方法来防止在正则表达式中捕获组和反向引用?
您的正则表达式非常幼稚。 (事实上,我很难找到 是 与您的正则表达式匹配的组构造。)
为了避免误报,例如 [(bar)]
,有必要从左到右 parse/match 整个模式。我想出了这个正则表达式:
^(?:\[(?:\.|[^\]])*\]|\(\?:|[^(\]|\\D|\(\?[gmixsu])*$
解释:
^ # start of string anchor
(?: # this group matches a single valid expression:
# character classes:
\[ # the opening [
(?:
\. # any escaped character
| # or
[^\]] # anything that's not a closing ]
)* # any number of times
\] # the closing ]
|
# non-capturing groups:
\(\?: # (?: literally
|
# normal characters (anything that's not a backslash or (
[^(\]
|
# meta sequences like \s
\\D
|
# inline modifiers like (?i)
\(\?[gmixsu]
)* # any number of valid expressions.
$ # end of string anchor
P.S.: 这个正则表达式不保证模式有效。 (编译模式仍然会失败。)
正则表达式语言不是正则语言,因此无法通过正则表达式将其可靠地分成有意义的部分(请参阅 RegEx match open tags except XHTML self-contained tags 以了解 HTML 的相同情况)。
为什么不使用 Python 自己的解析器来执行此操作?
>>> r="whate(ever)(?:\1)"
>>> import sre_parse #the module used by `re' internally for regex parsing
>>> sre_parse.parse(r)
[('literal', 119), ('literal', 104), ('literal', 97), ('literal', 116),
('literal', 101), ('subpattern', (1, [('literal', 101), ('literal', 118), ('lit
eral', 101), ('literal', 114)])), ('subpattern', (None, [('groupref', 1)]))]
如您所见,这是一棵解析树,您对第一个元素中非 None
和 groupref
的 subpattern
节点感兴趣。
我有一个 python 应用程序需要处理用户提交的正则表达式。 由于性能方面的考虑,我想禁止捕获组和反向引用。
我的想法是使用另一个正则表达式来验证用户提交的正则表达式不包含任何命名或未命名的组捕获,如下所示:
def validate_user_regex(pattern):
if re.match('[^\\]\((?:\?P).*?[^\\]\)', pattern) is not None:
return False
return True
虽然我认为我的想法可能适用于捕获组,但我不确定这是否会阻止各种反向引用。 那么有没有更聪明的方法来防止在正则表达式中捕获组和反向引用?
您的正则表达式非常幼稚。 (事实上,我很难找到 是 与您的正则表达式匹配的组构造。)
为了避免误报,例如 [(bar)]
,有必要从左到右 parse/match 整个模式。我想出了这个正则表达式:
^(?:\[(?:\.|[^\]])*\]|\(\?:|[^(\]|\\D|\(\?[gmixsu])*$
解释:
^ # start of string anchor
(?: # this group matches a single valid expression:
# character classes:
\[ # the opening [
(?:
\. # any escaped character
| # or
[^\]] # anything that's not a closing ]
)* # any number of times
\] # the closing ]
|
# non-capturing groups:
\(\?: # (?: literally
|
# normal characters (anything that's not a backslash or (
[^(\]
|
# meta sequences like \s
\\D
|
# inline modifiers like (?i)
\(\?[gmixsu]
)* # any number of valid expressions.
$ # end of string anchor
P.S.: 这个正则表达式不保证模式有效。 (编译模式仍然会失败。)
正则表达式语言不是正则语言,因此无法通过正则表达式将其可靠地分成有意义的部分(请参阅 RegEx match open tags except XHTML self-contained tags 以了解 HTML 的相同情况)。
为什么不使用 Python 自己的解析器来执行此操作?
>>> r="whate(ever)(?:\1)"
>>> import sre_parse #the module used by `re' internally for regex parsing
>>> sre_parse.parse(r)
[('literal', 119), ('literal', 104), ('literal', 97), ('literal', 116),
('literal', 101), ('subpattern', (1, [('literal', 101), ('literal', 118), ('lit
eral', 101), ('literal', 114)])), ('subpattern', (None, [('groupref', 1)]))]
如您所见,这是一棵解析树,您对第一个元素中非 None
和 groupref
的 subpattern
节点感兴趣。