我想在 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
您必须将正则表达式构建为字符串:
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
的使用,以便如果您的文本包含特殊字符,它们将不会被解释为特殊字符。
从 python 3.6 开始,您还可以使用 Literal String Interpolation,“f-strings”。在您的特定情况下,解决方案是:
if re.search(rf"\b(?=\w){TEXTO}\b(?!\w)", subject, re.IGNORECASE):
...do something
编辑:
由于评论中有一些关于如何处理特殊字符的问题,我想扩展我的答案:
原始字符串('r'):
在处理正则表达式中的特殊字符时,您必须了解的主要概念之一是区分字符串文字和正则表达式本身。很好解释here:
简而言之:
假设您想匹配字符串 \boundary
,而不是在 TEXTO
之后查找单词边界 \b
。你必须写:
TEXTO = "Var"
subject = r"Var\boundary"
if re.search(rf"\b(?=\w){TEXTO}\\boundary(?!\w)", subject, re.IGNORECASE):
print("match")
这仅适用于我们使用的是原始字符串(正则表达式以 'r' 开头),否则我们必须在正则表达式中写入“\\\\boundary”(四个反斜杠)。此外,如果没有 '\r',\b' 将不再转换为单词边界,而是转换为退格!
转义:
基本上在任何特殊字符前面放置一个退格键。因此,如果您希望 TEXTO 中有一个特殊字符,则需要编写:
if re.search(rf"\b(?=\w){re.escape(TEXTO)}\b(?!\w)", subject, re.IGNORECASE):
print("match")
注意:对于任何版本 >= python 3.7:!
、"
、%
、'
、,
、/
、:
、;
、<
、=
、>
、@
和 `
不会被转义。只有在正则表达式中有意义的特殊字符仍然被转义。自 Python 3.3 起,_
未转义。(s. here)
大括号:
如果要使用 f 字符串在正则表达式中使用量词,则必须使用双花括号。假设您要匹配 TEXTO 后跟 2 位数字:
if re.search(rf"\b(?=\w){re.escape(TEXTO)}\d{{2}}\b(?!\w)", subject, re.IGNORECASE):
print("match")
fr"foo{{1,5}}"
(双括号)
if re.search(r"\b(?<=\w)%s\b(?!\w)" % TEXTO, subject, re.IGNORECASE):
这会将 TEXTO 中的内容作为字符串插入到正则表达式中。
rx = r'\b(?<=\w){0}\b(?!\w)'.format(TEXTO)
我发现通过将多个较小的模式串在一起来构建正则表达式模式非常方便。
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')]
我同意以上所有内容,除非:
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
您可以使用 format
grammer suger 尝试另一种用法:
re_genre = r'{}'.format(your_variable)
regex_pattern = re.compile(re_genre)
我需要搜索彼此相似的用户名,而 Ned Batchelder 所说的非常有用。但是,当我使用 re.compile 创建我的搜索词时,我发现输出更清晰:
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.
这是您可以使用的另一种格式(在 python 3.7 上测试)
regex_str = r'\b(?<=\w)%s\b(?!\w)'%TEXTO
我发现当你不能使用 {}
作为变量时它很有用(这里用 %s
代替)
您也可以为此使用 format 关键字。Format 方法会将 {} 占位符替换为您作为参数传递给 format 方法的变量。
if re.search(r"\b(?=\w)**{}**\b(?!\w)".**format(TEXTO)**, subject, re.IGNORECASE):
# Successful match**strong text**
else:
# Match attempt failed
更多示例
我有带有流文件的 configus.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)
不定期副业成功案例分享
r'' + foo + 'bar'
?re.escape(foo)
,则不需要r''
,无论如何您都应该这样做。实际上,我认为re
将给出的任何内容解释为 unicode 字符串,无论您是否为r
加上前缀。