如何在正则表达式中使用变量?

我想在regex中使用variable,如何在Python中做到这一点?

TEXTO = sys.argv[1]


if re.search(r"\b(?=\w)TEXTO\b(?!\w)", subject, re.IGNORECASE):
# Successful match
else:
# Match attempt failed
326206 次浏览
rx = r'\b(?<=\w){0}\b(?!\w)'.format(TEXTO)
if re.search(r"\b(?<=\w)%s\b(?!\w)" % TEXTO, subject, re.IGNORECASE):

这将把TEXTO中的内容作为字符串插入到正则表达式中。

你必须以字符串的形式构建正则表达式:

TEXTO = sys.argv[1]
my_regex = r"\b(?=\w)" + re.escape(TEXTO) + r"\b(?!\w)"


if re.search(my_regex, subject, re.IGNORECASE):
etc.

注意re.escape的使用,这样如果你的文本有特殊字符,它们就不会被这样解释。

我同意以上所有观点,除非:

sys.argv[1]类似于Chicken\d{2}-\d{2}An\s*important\s*anchor

sys.argv[1] = "Chicken\d{2}-\d{2}An\s*important\s*anchor"

你不会想要使用re.escape,因为在这种情况下,你希望它表现得像一个正则表达式

TEXTO = sys.argv[1]


if re.search(r"\b(?<=\w)" + TEXTO + "\b(?!\w)", subject, re.IGNORECASE):
# Successful match
else:
# Match attempt failed

我需要搜索彼此相似的用户名,Ned Batchelder说的非常有用。然而,当我使用re.compile创建我的re搜索项时,我发现我有更清晰的输出:

pattern = re.compile(r"("+username+".*):(.*?):(.*?):(.*?):(.*)"
matches = re.findall(pattern, lines)

输出可以使用以下命令打印:

print(matches[1]) # prints one whole matching line (in this case, the first line)
print(matches[1][3]) # prints the fourth character group (established with the parentheses in the regex statement) of the first line.

我发现通过将多个较小的模式串在一起来构建正则表达式模式非常方便。

import re


string = "begin:id1:tag:middl:id2:tag:id3:end"
re_str1 = r'(?<=(\S{5})):'
re_str2 = r'(id\d+):(?=tag:)'
re_pattern = re.compile(re_str1 + re_str2)
match = re_pattern.findall(string)
print(match)

输出:

[('begin', 'id1'), ('middl', 'id2')]

你也可以使用format关键字。Format方法会将{}占位符替换为您传递给Format方法作为参数的变量。

if re.search(r"\b(?=\w)**{}**\b(?!\w)".**format(TEXTO)**, subject, re.IGNORECASE):
# Successful match**strong text**
else:
# Match attempt failed

你可以尝试使用format语法糖的另一种用法:

re_genre = r'{}'.format(your_variable)
regex_pattern = re.compile(re_genre)

从python 3.6开始,你也可以使用字面值字符串插值, "f-string "。在你的具体情况下,解决方案是:

if re.search(rf"\b(?=\w){TEXTO}\b(?!\w)", subject, re.IGNORECASE):
...do something

编辑:

由于评论中有一些关于如何处理特殊字符的问题,我想扩展我的回答:

原始字符串('r'):

在处理正则表达式中的特殊字符时,您必须了解的一个主要概念是区分字符串字面量和正则表达式本身。在这里解释得很好:

简而言之:

让我们说,不是在TEXTO之后找到一个单词边界\b,而是要匹配字符串\boundary。你必须写:

TEXTO = "Var"
subject = r"Var\boundary"


if re.search(rf"\b(?=\w){TEXTO}\\boundary(?!\w)", subject, re.IGNORECASE):
print("match")

这只是因为我们使用了一个原始字符串(正则表达式前面有'r'),否则我们必须写入"\\\\boundary"在正则表达式中(四个反斜杠)。此外,如果没有'\r', \b'将不再转换为单词边界,而是转换为退格!

re.escape:

基本上就是在任何特殊字符前加一个反斜杠。因此,如果你希望TEXTO中有一个特殊字符,你需要写:

if re.search(rf"\b(?=\w){re.escape(TEXTO)}\b(?!\w)", subject, re.IGNORECASE):
print("match")

注意:对于任何版本>= python 3.7: !"%',/:;<="0, "1和"2不会转义。只有在正则表达式中有意义的特殊字符仍然被转义。"3自Python 3.3以来没有转义。"4)

花括号:

如果要在使用f-字符串的正则表达式中使用量词,则必须使用双花括号。让我们假设你想匹配TEXTO后面恰好有2个数字:

if re.search(rf"\b(?=\w){re.escape(TEXTO)}\d\{\{2}}\b(?!\w)", subject, re.IGNORECASE):
print("match")

更多的例子

我有config .yml 与流量文件

"pattern":
- _(\d{14})_
"datetime_string":
- "%m%d%Y%H%M%f"

我使用的python代码

data_time_real_file=re.findall(r""+flows[flow]["pattern"][0]+"", latest_file)

下面是你可以使用的另一种格式(在python 3.7上测试)

regex_str = r'\b(?<=\w)%s\b(?!\w)'%TEXTO

我发现它是有用的,当你不能使用{}变量(这里替换为%s)

from re import search, IGNORECASE


def is_string_match(word1, word2):
#  Case insensitively function that checks if two words are the same
# word1: string
# word2: string | list


# if the word1 is in a list of words
if isinstance(word2, list):
for word in word2:
if search(rf'\b{word1}\b', word, IGNORECASE):
return True
return False


# if the word1 is same as word2
if search(rf'\b{word1}\b', word2, IGNORECASE):
return True
return False

is_match_word = is_string_match("Hello", "hELLO")
True

is_match_word = is_string_match("Hello", ["Bye", "hELLO", "@vagavela"])
True

is_match_word = is_string_match("Hello", "Bye")
False