✅ 什么叫“正则字符串”?
在正则表达式里,一些字符有 特殊意义,比如:
| 字符 | 正则意思 |
|---|---|
. |
匹配任意一个字符(除了换行) |
* |
匹配前一个字符出现 0 次或多次 |
+ |
匹配前一个字符出现 1 次或多次 |
[] |
字符集 |
\b |
单词边界 |
| |
或 |
所以:正则表达式不是普通字符串!
如果你直接用这些字符写搜索词,正则会误解它们的意思。
❗举个例子:什么叫“不安全”的关键词?
假设你写了一个关键词是:
term = "heart.attack"
你本来是想查 "heart.attack" 这个字面文本,结果你在正则里直接写:
re.search(r"heart.attack", query)
这会匹配:
heartXattack
只要 heart 和 attack 中间有任意一个字符(如空格、字母、标点等),都能匹配。因为 . 是正则里的“任意字符”符号,不是你想的“句点”。
这就叫:不安全 —— 它被误当成正则符号了。
✅ 什么是 “安全”的正则字符串?
就是你把这个关键词里的所有特殊字符都变成字面意思(原样匹配)。
例如:
import re
term = "heart.attack"
safe_term = re.escape(term)
print(safe_term) # 输出: heart\.attack
它自动把 . 转换为 \.,这样正则就不会把它当作“任意字符”,而是当作真正的句号。
🔧 再举几个例子
| 原始字符串 |
re.escape() 后的结果 |
|---|---|
heart.attack |
heart\.attack |
high blood pressure |
high\ blood\ pressure |
alzheimer's |
alzheimer\'s |
a+b=c |
a\+b=c |
[test] |
\[test\] |
✅ 所以:
当你要用用户输入的关键词当成正则模式的一部分时,一定要先用 re.escape() 处理!
否则,如果用户输进来的内容里有:
-
.,+,*,|,[,],(,),?等等
都会被当作正则语法执行,可能会出错或匹配错误。
📌 总结一句话:
re.escape(term) 的作用是:让正则表达式“只把它当作文字看”,而不是去执行里面的符号。
再举个例子,我们来详细拆解这一句代码:
re.search(r"\b" + re.escape(term) + r"\b", query.lower())
它的功能是:
👉 判断 query 中是否包含某个完整的关键词或词组 term,并且只匹配整个词,不会匹配成分词或子串。
一步一步来看每个部分的意思👇
🔧 1. re.search(pattern, string)
这是 Python 标准库 re(正则表达式)中的一个函数,用来在字符串中查找某个正则模式是否存在。
-
pattern: 要找的正则表达式 -
string: 要在里面查找的目标文本
例如:
import re
re.search("apple", "I like apple pie") # ✅ 找到了
re.search("apple", "I like pineapple") # ✅ 也找到了(但不是我们想要的)
问题是:它会匹配 部分词,而我们只想匹配 完整词(whole word)。
🔧 2. \b 是什么意思?
\b 是一个 正则表达式的特殊符号,代表 单词边界(word boundary),例如:
| 匹配目标 |
\bapple\b 是否匹配? |
说明 |
|---|---|---|
I like apple. |
✅ 匹配 | 前后是空格和句号,是边界 |
I like pineapple. |
❌ 不匹配 |
apple 不在“单词边界” |
applepie |
❌ 不匹配 | 没有空格或标点分隔 |
apple pie |
✅ 匹配 | 是独立单词 |
🔧 3. re.escape(term)
如果关键词 term 里面有一些特殊字符(比如句点、加号、撇号等),正则会把它们当成操作符。
re.escape() 的作用是:
👉 把普通字符串变成“正则安全字符串”,例如:
re.escape("alzheimer's") → "alzheimer's" → 实际变成 "alzheimer\'s"
re.escape("high blood pressure") → "high\\ blood\\ pressure"
这样就不会误触发正则的语法规则。
📌 所以组合起来这句代码:
re.search(r"\b" + re.escape(term) + r"\b", query.lower())
等价于:
“在小写化后的
query里面,查找是否存在一个完整的、等于term的词/短语”。
✅ 举个例子彻底搞清楚
假设:
query = "My grandfather had a heart attack."
term = "heart attack"
执行:
re.search(r"\bheart attack\b", query.lower())
✔ query.lower() 会变成 "my grandfather had a heart attack."
✔ \bheart attack\b 会查找是否有完整的 "heart attack",前后是边界
结果:✅ 找到了
如果是这个:
query = "He had aheartattack suddenly." # 连写了
结果:❌ 不会匹配,因为没有边界。
🔚 总结
| 组成部分 | 含义 |
|---|---|
re.search() |
正则查找是否有匹配 |
r"\b...\b" |
匹配完整的单词或短语 |
re.escape(term) |
把关键词变成安全的正则字符串 |
query.lower() |
忽略大小写地查找 |