我正在尝试匹配文件名中由点号分隔的任意数量的文字#符号。文字#符号在文件名的最后一个元素的情况下,必须在两边用点号EXCEPT分隔。我可以创建一个模式,该模式执行第一个(匹配点号所包围的任何文字#符号),但是我却不能这样做,而同时允许第二个模式(文件名以文字#符号结尾且没有尾随点)。>
例如,以下将匹配:
bob.#
bob.#.
bob.#.exr
bob.##.mary.tif
bob.####.png
以下内容不匹配:
bob.#string.exr
bob.string#.exr
到目前为止,我的模式(在python中表示为原始字符串)是
(.*)(\.#+)((?:\.+.*|$))
很遗憾,它与我列表中的第一项不匹配:bob。#
我本以为最后一个不受约束的小组基本上会写成:
匹配文字点后跟0个或多个字符
OR
匹配字符串的结尾
但是在regexr.com上测试表明它与bob不匹配。#
谢谢您提供任何线索!
答案 0 :(得分:3)
^\w*?\.(#+)(\.\w*?)*?$
此正则表达式匹配一个点前面的任意数量的单词字符(包括无),匹配一个或多个八字符号,然后可选地匹配一个点和多个单词/字符。
^\w*?\.(#+)(\.\w*?)*?$
^ anchor to the start of the line
\w*? get as many word characters as you want, but as few as you need
\. match . literally
(#+) match one or more # literally. grouped for your convenience if you want to count how many times they appear or something.
( )*? match zero or more of this group:
\. a literal dot...
\w*? ...and zero or more word characters, as few as needed.
$ ensure the string ends with this group.
有关此正则表达式的几点说明:
\w*
通常比.*
更安全,更快捷-它专门查找单词字符a-z, A-Z, 0-9, _
而不是任何符号。通常,如果您可以使正则表达式更具体,则应避免冒险catastrophic backtracking! 答案 1 :(得分:2)
如果您希望它匹配整个元序列,则为以下一种:
import re
pattern = re.compile(r'(\w+\.\#+(?:\.|$)\w*\.*\w*)')
test = ['bob.#', 'bob.#.', 'bob.#.exr', 'bob.##.mary.tif', 'bob.####.png', 'bob.#string.exr', 'bob.string#.exr']
for t in test:
print(re.findall(pattern, t))
输出:
['bob.#']
['bob.#.']
['bob.#.exr']
['bob.##.mary.tif']
['bob.####.png']
[]
[]
答案 2 :(得分:0)
您的表情似乎运行良好,我仍将其修改为类似于以下的某种表情:
import re
regex = r"^([^.]*)(\.#+)(\..*)?$"
test_str ="""
bob.#
bob.#.
bob.#.exr
bob.##.mary.tif
bob.####.png
Whereas the following would not match:
bob.#string.exr
bob.string#.exr
"""
print(re.findall(regex, test_str,re.M))
[('\nbob', '.#', ''), ('bob', '.#', '.'), ('bob', '.#', '.exr'), ('bob', '.##', '.mary.tif'), ('bob', '.####', '.png')]
如果您想探索/简化/修改表达式,可以 在右上角的面板上进行了说明 regex101.com。如果您愿意, 也可以在this link中观看它的匹配方式 针对一些样本输入。
jex.im可视化正则表达式: