为什么我的正则表达式与r'string'匹配但不是'字符串'使用Python?

Jas*_*ett 9 python regex

正则表达式在Python中运行的方式是非常令人费解的,它让我每过一秒都更加愤怒.这是我的问题:

我明白这会产生一个结果:

re.search(r'\bmi\b', 'grand rapids, mi 49505)
Run Code Online (Sandbox Code Playgroud)

虽然这不是:

re.search('\bmi\b', 'grand rapids, mi 49505)
Run Code Online (Sandbox Code Playgroud)

那没关系.我得到了那么多.现在,我有一个正则表达式,它是这样生成的:

regex = '|'.join(['\b' + str(state) + '\b' for state in states])
Run Code Online (Sandbox Code Playgroud)

如果我现在这样做re.search(regex, 'grand rapids, mi 49505'),它失败的原因与第二个search()例子失败的原因相同.

我的问题:有什么方法可以做我想做的事情吗?

e-s*_*tis 14

anwser本身

regex = '|'.join([r'\b' + str(state) + r'\b' for state in states])
Run Code Online (Sandbox Code Playgroud)

这背后的原因是'r'前缀告诉Python不要分析你传递给它的字符串.如果你没有在字符串前放一个'r',Python将尝试将前面带有'\'的任何字符转换成一个特殊字符,以允许你输入断行(\n),制表符(\ t)等等容易.

当你这样做时'\b',你告诉Python创建一个字符串,分析它,并将'\ b'转换为'backspace',而当你这样做时r'\b',Python只存储'\'然后'b',这就是你想要的正则表达式.始终使用'r'作为正则表达式模式的字符串.

'r'表示法称为'原始字符串',但这是误导性的,因为在Python内部没有原始字符串这样的东西.只需将其视为一种告诉Python避免过于聪明的方法.

Python <3.0中还有另一种表示法u'string,它告诉Python将字符串存储为unicode.你可以将两者结合起来:ur"é\n"将"\bé"存储为unicode,同时u"é\n"将"é"存储为换行符.

一些改进代码的方法:

regex = '|'.join(r'\b' + str(state) + r'\b' for state in states)
Run Code Online (Sandbox Code Playgroud)

删除了额外的[].它告诉Python不要在内存中存储您生成的值列表.我们可以在这里完成,因为我们不打算重复使用您正在创建的列表,因为您直接在join()其他地方使用它.

regex = '|'.join(r'\b%s\b' % state for state in states)
Run Code Online (Sandbox Code Playgroud)

这将自动处理字符串转换,并且更短更干净.在Python中格式化字符串时,请考虑%运算符.

如果状态包含状态邮政编码列表,那么应该存储为字符串,而不是int.在这种情况下,您可以跳过类型转换并进一步缩短它:

regex = r'\b%s\b' % r'\b|\b'.join(states)
Run Code Online (Sandbox Code Playgroud)

最终,您可能根本不需要正则表达式.如果您只关心其中一个邮政编码是否在给定字符串中,您可以使用in(检查项目是否在可迭代中,如果字符串在列表中):

matches = [s for s in states if s in 'grand rapids, mi 49505']
Run Code Online (Sandbox Code Playgroud)

遗言

我知道你在学习一门新语言时可能会感到沮丧,但要花点时间给你的问题一个正确的标题.在本网站中,标题应以问号结尾,并提供有关问题的具体细节.

  • 该死的.等等,我可能是意大利人! (2认同)
  • 只是一个补充的词.可以删除`[]`,因为`(r'\ b'+ str(state)+ r'\ b'表示状态中的状态)`本身返回一个`<type'generator'>`,它可以被迭代函数`next`并被接受作为''.join()的参数.所以没有必要首先从这个迭代器构造一个列表. (2认同)