转义正则表达式字符串
- 2024-11-28 08:37:00
- admin 原创
- 5
问题描述:
我想使用用户的输入作为正则表达式模式来搜索某些文本。这可行,但我该如何处理用户输入在正则表达式中有意义的字符的情况?
例如,用户想要搜索 Word (s)
:正则表达式引擎会将(s)
作为一个组。我希望它将其视为字符串"(s)"
。我可以replace
根据用户输入运行并将 替换(
为(
并将 替换)
为)
但问题是我需要对每个可能的正则表达式符号进行替换。
您知道一些更好的方法吗?
解决方案 1:
使用该re.escape()
函数实现此目的:
4.2.3re
模块内容
转义(字符串)
返回所有非字母数字都带有反斜杠的字符串;如果您想要匹配可能包含正则表达式元字符的任意文字字符串,这很有用。
一个简单的例子,搜索任何出现的提供的字符串(可选后跟“s”),并返回匹配对象。
def simplistic_plural(word, text):
word_or_plural = re.escape(word) + 's?'
return re.match(word_or_plural, text)
解决方案 2:
您可以使用re.escape()
:
re.escape(string) 返回所有非字母数字都带有反斜杠的字符串;如果您想匹配可能包含正则表达式元字符的任意文字字符串,这很有用。
>>> import re
>>> re.escape('^a.*$')
'\\^a\\.\\*\\$'
如果您使用的 Python 版本 <3.7,这将转义不属于正则表达式语法的非字母数字。
如果您使用的 Python 版本 < 3.7 但 >= 3.3,这将转义不属于正则表达式语法的非字母数字,但特殊下划线 ( )除外_
。
解决方案 3:
不幸的是,re.escape()
不适合替换字符串:
>>> re.sub('a', re.escape('_'), 'aa')
'\\_\\_'
一个解决方案是将替换放入 lambda 中:
>>> re.sub('a', lambda _: '_', 'aa')
'__'
因为 lambda 的返回值被视为re.sub()
文字字符串。
解决方案 4:
re.escape
做得太多了,它还会转义空格、反斜杠……
仅转义正则表达式特殊字符][()?*+.^$
import re
def regex_escape_fixed_string(string):
"escape fixed string for regex"
if type(string) == bytes:
return re.sub(rb"[][(){}?*+.^$]", lambda m: b"\\\" + m.group(), string)
return re.sub(r"[][(){}?*+.^$]", lambda m: "\\\" + m.group(), string)
assert (
regex_escape_fixed_string("a[b]c(d)e{f}g?h*i+j.k^l$m") ==
'a\\[b\\]c\\(d\\)e\\{f\\}g\\?h\\*i\\+j\\.k\\^l\\$m'
)
解决方案 5:
通常,对输入到正则表达式的字符串进行转义会使正则表达式从字面上考虑这些字符。记住,通常您在计算机中输入字符串,然后计算机插入特定字符。当您在编辑器中看到它时`,它实际上不是一个新行,直到解析器决定它是。它是两个字符。一旦您将其传递出去,python
print就会显示它并将其解析为一个新行,但在编辑器中看到的文本中,它可能只是反斜杠字符后跟 n。如果您
"
"这样做,那么 python 将始终将其解释为您输入的原始内容(据我所知)。使事情进一步复杂化的是,正则表达式还有另一种语法/语法。正则表达式解析器对它接收的字符串的解释与 python 的打印不同。我相信这就是为什么我们建议传递像
r"(
+)-- 这样的原始字符串,以便正则表达式接收您实际输入的内容。但是,正则表达式将收到一个括号,并且不会将其作为文字括号进行匹配,除非您使用**正则表达式自己的语法规则**明确告诉它。为此,您需要
r"(un ( x : nat ) :)"`在这里第一个括号将不会匹配,因为它是一个捕获组,因为缺少反斜杠,但第二个括号将作为文字括号进行匹配。
因此,我们通常会re.escape(regex)
转义那些我们想要按字面意思解释的东西,也就是那些通常会被正则表达式解析器忽略的东西,例如括号、空格等,这些都会被转义。例如我的应用程序中的代码:
# escapes non-alphanumeric to help match arbitrary literal string, I think the reason this is here is to help differentiate the things escaped from the regex we are inserting in the next line and the literal things we wanted escaped.
__ppt = re.escape(_ppt) # used for e.g. parenthesis ( are not interpreted as was to group this but literally
例如查看这些字符串:
_ppt
Out[4]: '(let H : forall x : bool, negb (negb x) = x := fun x : bool =>HEREinHERE)'
__ppt
Out[5]: '\\(let\\ H\\ :\\ forall\\ x\\ :\\ bool,\\ negb\\ \\(negb\\ x\\)\\ =\\ x\\ :=\\ fun\\ x\\ :\\ bool\\ =>HEREinHERE\\)'
print(rf'{_ppt=}')
_ppt='(let H : forall x : bool, negb (negb x) = x := fun x : bool =>HEREinHERE)'
print(rf'{__ppt=}')
__ppt='\\(let\\ H\\ :\\ forall\\ x\\ :\\ bool,\\ negb\\ \\(negb\\ x\\)\\ =\\ x\\ :=\\ fun\\ x\\ :\\ bool\\ =>HEREinHERE\\)'
我相信双反斜杠的存在是为了让正则表达式收到一个文字反斜杠。
顺便说一句,我很惊讶它打印的是双反斜杠而不是单反斜杠。如果有人能对此发表评论,我将不胜感激。我还想知道现在如何在正则表达式中匹配文字反斜杠。我假设它是 4 个反斜杠,但老实说,由于原始字符串 r 构造,我原本预计只需要 2 个。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件