【问题标题】:Find a substring with conditions with a regex使用正则表达式查找具有条件的子字符串
【发布时间】:2018-08-29 02:04:53
【问题描述】:

我想返回False 仅当子字符串前后都有字母:

例如给定目标'at'

strings = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']

我想返回[True, True, True, False]

我现在有:

def foo(p,i):
    if p.findall(i):
        return True
    return False

pat = re.compile(r'\bat\b')
[foo(pat,i) for i in strings]

返回[True, False, False, False]

【问题讨论】:

  • 试试(?<=[a-z])at(?=[a-z])\Bat\B 几乎是一样的。
  • 你能再解释一下I want to return FALSE only if the substring has alphabet letter(s) both before AND after it:吗?
  • 你不用re.findallre.search就够了。由于您需要测试匹配,[^\W\d_]at[^\W\d_] 正则表达式可以(它甚至可以匹配任何 Unicode 字母)。如果只需要匹配 ASCII,[a-zA-Z]at[a-zA-Z] 就可以了。

标签: python regex string python-3.x substring


【解决方案1】:

这是一个使用re.searchmap 函数的可读单行样式解决方案:

import re

strings = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']

s = list(map(lambda s: not re.search(r'[\w]at[\w]', s), strings))

print(s)   # [True, True, True, False]

【讨论】:

    【解决方案2】:

    对于您的特定问题,这将是一个非常简单的解决方案。

    def foo(text):
        for x in range(len(text)):
            if text[x] == 'a' and text[x+1] == 't':
                if text[x-1].isalnum() and text[x+2].isalnum():
                    return False
        return True
    

    【讨论】:

      【解决方案3】:

      您可以使用re.search 而不是re.findall,因为您只测试一个字符串 一场比赛。

      如果你只需要匹配 ASCII,[a-zA-Z] 在一个单词的两边都可以。

      使用

      import re
      strs = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']
      
      def foo(p,i):
          return False if p.search(i) else True
      
      word = 'at'
      pat = re.compile(r'[a-zA-Z]{}[a-zA-Z]'.format(word))
      print([foo(pat,i) for i in strs])
      # => [True, True, True, False]
      

      Python demo

      如果您打算使用 Unicode 字母,请将 [a-zA-Z] 替换为 [^\W\d_]。在 Python 3 中,默认使用 re.U,在 Python 2 中,您需要添加它。

      【讨论】:

      • 谢谢,维克托!如果字符串不是太长[a-zA-Z][^\W\d_]在速度上应该差不多吧?
      • @BenLiu 是用Python对外扩展的,所以[a-zA-Z]应该更快。
      • 刚刚做到了!非常感谢您的帮助。
      【解决方案4】:

      试试下面的正则表达式

      def foo(p,i):
          if p.findall(i):
              return True
          return False
      pat = re.compile(r'.*([\w]at[\w]).*')
      out  = [not foo(pat,i) for i in strings]
      # [True, True, True, False]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-16
        • 2012-05-12
        相关资源
        最近更新 更多