【问题标题】:Check String for / against Characters in Python在 Python 中检查字符串是否与字符相对应
【发布时间】:2009-11-11 11:24:30
【问题描述】:

我需要能够区分可以包含字母和数字的字符串与可以包含数字、冒号和连字符的字符串之间的区别 。

>>> def checkString(s):
...   pattern = r'[-:0-9]'
...   if re.search(pattern,s):
...     print "Matches pattern."
...   else:
...     print "Does not match pattern."

# 3 Numbers seperated by colons. 12, 24 and minus 14
>>> s1 = "12:24:-14"
# String containing letters and string containing letters/numbers.
>>> s2 = "hello"
>>> s3 = "hello2"

当我对上述每个字符串运行checkString 方法时:

>>>checkString(s1)
Matches Pattern.
>>>checkString(s2)
Does not match Pattern.
>>>checkString(s3)
Matches Pattern

s3 是唯一不做我想做的事的人。我希望能够创建一个允许数字、冒号和连字符的正则表达式,但不包括其他所有内容(或只是字母字符)。谁能指出我正确的方向?

编辑:

因此,我需要一个可以接受的正则表达式:

229            // number
187:657        //two numbers
187:678:-765   // two pos and 1 neg numbers

然后拒绝:

Car          //characters
Car2         //characters and numbers

【问题讨论】:

  • 你想肯定匹配字母+数字的东西,还是不想?您在开头声明匹配字母+数字,但随后您说您不想匹配 s3(但您确实想匹配 s2)。

标签: python regex


【解决方案1】:

你需要匹配整个字符串,而不是像现在这样的单个字符:

>>> re.search('^[-:0-9]+$', "12:24:-14")
<_sre.SRE_Match object at 0x01013758>
>>> re.search('^[-:0-9]+$', "hello")
>>> re.search('^[-:0-9]+$', "hello2")

解释正则表达式:

  • 在方括号内(字符类):匹配数字 0 到 9、连字符和冒号,只匹配一次。
  • + 是一个量词,表示前面的表达式应尽可能多地匹配,但至少匹配一次。
  • ^ 和 $ 匹配字符串的开头和结尾。对于单行字符串,它们等效于 \A 和 \Z。

这样,您将整个字符串的内容限制为至少一个字符长,并包含字符类中字符的任何排列。您之前所做的是从主题字符串中的字符类中搜索单个字符。这就是为什么 s3 包含一个匹配的数字。

【讨论】:

  • 您的正则表达式将无法匹配第二个字符串,他们指出这不是他们想要的。
  • 让我们再读一遍这个问题:s3 是唯一没有做我想做的事。 s2 和 s3 都不应该匹配。
  • 嗯,我猜有点含糊其辞。 “s3 is the only one that doesn't do what I want”可以解释为“唯一一个我不想匹配”。
  • @_bravado:对我来说,从一开始就很清楚 :) 我的解决方案显然有效。
  • 我能问一下'^'是做什么的吗?或者您能解释一下每个符号的含义(在方括号之前/之后)吗?
【解决方案2】:

SilentGhost 的答案非常好,但请注意,它也会匹配像 "---::::" 这样没有数字的字符串。

我认为您正在寻找这样的东西:

'^(-?\d+:)*-?\d+$'
  • ^ 匹配行首。
  • (-?\d+:)* 可能 - 符号,至少一个数字,一个冒号。整个模式 0 次或多次。
  • -?\d+ 然后是模式,至少一次,没有冒号
  • $行尾

这将更好地匹配您描述的字符串。

【讨论】:

    【解决方案3】:
    pattern = r'\A([^-:0-9]+|[A-Za-z0-9])\Z'
    

    【讨论】:

      【解决方案4】:

      你的正则表达式几乎没问题;你只需要让它匹配整个字符串。此外,正如评论者指出的那样,在这种情况下,您实际上并不需要原始字符串(字符串上的 r 前缀)。瞧:

      def checkString(s):
        if re.match('[-:0-9]+$', s):
          print "Matches pattern."
        else:
          print "Does not match pattern."
      

      “+”表示“匹配一个或多个前面的表达式”。 (这将使 checkString 在空字符串上返回 False。如果您希望在空字符串上返回 True,请将 '+' 更改为 '*'。)'$' 表示“匹配字符串的结尾”。

      re.match 表示“字符串必须匹配从第一个字符开始的正则表达式”; re.search 的意思是“正则表达式可以匹配字符串中任意位置的序列”。

      另外,如果你喜欢过早优化——谁不喜欢!——请注意,'re.match' 每次都需要编译正则表达式。这个版本只编译一次正则表达式:

      __checkString_re = re.compile('[-:0-9]+$')
      def checkString(s):
        global __checkString_re
        if __checkString_re.match(s):
          print "Matches pattern."
        else:
          print "Does not match pattern."
      

      【讨论】:

      • 试试这个:&gt;&gt;&gt; re.match('[-:0-9]+', "2hello2")
      • 为什么要声明编译后的字符串global?通过阻止函数关闭来节省空间?
      • steveha:只是为了表明意图。如果删除该行,所编写的函数将正常工作。就我个人而言,我发现关于 Python 何时自动在模块范围内查找的规则让你很烦,所以我倾向于使用“全局”而不是大多数。
      猜你喜欢
      • 2015-07-07
      • 2017-02-09
      • 2013-08-21
      • 2013-01-09
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多