Python 中的通配符匹配

Wildcard matching in Python

我有一个名为 Pattern 的 class,其中有两个方法,equates 和 setwildcard。等于returns子串在字符串中最先出现的索引,setwildcard在子串中设置通配符

所以

p = Pattern('xyz')
t = 'xxxxxyz'
p.equates(t)

Returns 4

还有

p = Pattern('x*z', '*')
t = 'xxxxxgzx'
p.equates(t)

Returns 4、因为*是通配符,可以匹配t内的任意字母,只要x和z匹配即可。 实现它的最佳方法是什么?

看起来您实际上是在实现正则表达式的一个子集。幸运的是,Python 有一个库 built-in!如果您不熟悉正则表达式(或者他们的朋友称它们为正则表达式)的工作原理,我强烈建议您通读 documentation for them.

无论如何,我认为函数 re.search 正是您要找的。它的第一个参数是要匹配的模式,第二个参数是要匹配的字符串。如果模式匹配,search returns 一个 SRE_Match 对象,它有一个 #start() 方法,该方法 returns 匹配开始的索引。

要使用示例中的数据:

 import re
 start_index = re.search(r'x.z', 'xxxxxgzg').start()

请注意,在正则表达式中,. - 而不是 * - 是通配符,因此您必须将它们替换为您正在使用的模式。

正如接受的答案所暗示的那样,正则表达式是处理问题的一种方法。不过,如果您需要更简单的模式(例如 Unix shell 风格的通配符),那么 fnmatch 内置库可以提供帮助:

表达式:

  • * - 匹配所有内容
  • ? - 匹配任何单个字符
  • [seq] - 匹配 seq
  • 中的任何字符
  • [!seq] - 匹配任何不在 seq
  • 中的字符

因此,例如,试图找到与 localhost:

匹配的任何内容
import fnmatch

my_pattern = "http://localhost*"
name_to_check = "http://localhost:8080"

fnmatch.fnmatch(name_to_check, my_pattern) # True

这样做的好处是 / 不被视为特殊字符,因此对于 filename/URL 匹配效果很好,无需预先转义所有斜杠!