我正在尝试使用正则表达式来捕获推文正文中的所有 Twitter 句柄。挑战在于我正在尝试处理这个问题
- 包含一个特定的字符串
- 长度未知
- 后面可以是
- 标点符号
- 空格
- 或字符串的结尾。
例如,对于这些字符串中的每一个,我都用斜体标记了我想要返回的内容。
"@handle what is your problem?" [RETURN '@handle']
"what is your problem @handle?" [RETURN '@handle']
"@123handle what is your problem @handle123?" [RETURN '@123handle', '@handle123']
这是我目前所拥有的:
>>> import re
>>> re.findall(r'(@.*handle.*?)\W','hi @123handle, hello @handle123')
['@123handle']
# This misses the handles that are followed by end-of-string
我尝试修改以包含允许字符串结尾字符的 或 字符。相反,它只返回整个字符串。
>>> re.findall(r'(@.*handle.*?)(?=\W|$)','hi @123handle, hello @handle123')
['@123handle, hello @handle123']
# This looks like it is too greedy and ends up returning too much
如何编写满足这两个条件的表达式?
请您参考如下方法:
您似乎在尝试匹配以 @ 开头的字符串,然后是 0+ 个单词字符,然后是 handle,然后是 0+ 个单词字符。
使用
r'@\w*handle\w*'
或者 - 避免在电子邮件中匹配 @+word 字符:
r'\B@\w*handle\w*'
参见 Regex 1 demo和 Regex 2 demo (\B 非单词边界要求在 @ 之前有一个非单词字符或字符串开头)。
请注意,.* 是一个贪婪的点匹配模式,它匹配除换行符以外的任何字符,尽可能多。 \w* 仅匹配 0+ 个字符(也尽可能多),但如果 re.UNICODE 标志未使用(并且未在您的代码中使用)。
import re
p = re.compile(r'@\w*handle\w*')
test_str = "@handle what is your problem?\nwhat is your problem @handle?\n@123handle what is your problem @handle123?\n"
print(p.findall(test_str))
# => ['@handle', '@handle', '@123handle', '@handle123']
