在re.search中返回NoneType与返回“”

时间:2014-07-21 05:59:22

标签: python regex search

我做了一些搜索,没有看到这个具体问题,但请告诉我这是否重复。

我编写了一个名为find_results的函数,它在字符串中搜索分隔符,然后在分隔符和新行之间返回任何内容:

def find_results(findme, separator, string):
    linelist=string.split('\n')
    for line in linelist:
        if re.search(findme, line):
            #Split based on the separator we were sent, but only on the first occurrance
            line = line.split(separator, 1)
            return line[1].strip()
        #End if line.find
    #end for loop
    return ""
#end find_results

这个功能效果很好,但我确信有更多的Pythonic方法可以完成相同的任务,坦率地说,我觉得有点愚蠢地为这么简单的事情调用自定义函数。

我最近学会了如何在正则表达式中使用集合,所以在某些情况下我已经能够用re.search调用替换该函数。如果分隔符是冒号,例如:

re.search("Preceeding\ Text:(.*)$", string).group(1)

这个问题是当没有结果时,我得到“NoneType”崩溃,因为“NoneType”上没有属性“group”。我可以使用if或try / except语句检查结果,但是这会使用find_results开始改变目的。

我的问题是:

  • 有没有办法暂停NoneType崩溃并让它返回“”(空白)?
  • 是否有不同的单行方式来实现这一目标?
  • 如果我必须使用自定义函数,是否有更多Pythonic(并且不那么尴尬)的方式来编写它?

4 个答案:

答案 0 :(得分:1)

使用str.partition

def find_results(findme, separator, s):
    tgt=s[s.find(findme):]
    return tgt.partition(separator)[2]

>>> find_results('Text', ':', 'Preceding Text:the rest')  
'the rest'
>>> find_results('Text', ';', 'Preceding Text:the rest')  
''
>>> find_results('text', ':', 'Preceding Text:the rest')  
''

由于分区总是返回一个3元素元组,最终元素为''未找到,这甚至可能是你的单行:

>>> s='Preceding Text:the rest'
>>> s[s.find('Text'):].partition(':')[2]
'the rest'
>>> s[s.find('Text'):].partition(';')[2]
''

如果findme部分或separator部分仅在正则表达式中有用,请使用re.split和try / except:

def find_re_results(findme, separator, s):
    p1=re.compile(findme)
    p2=re.compile(separator)
    m=p1.search(s)
    if m:
        li=p2.split(s[m.start():], maxsplit=1)
    else:
        return ''
    try:
        return li[1]
    except IndexError:
        return ''

演示:

>>> find_re_results('\d+', '\t', 'Preceding 123:;[]\\:the rest') 
''
>>> find_re_results('\d+', '\W+', 'Preceding 123:;[]\\:the rest') 
'the rest'
>>> find_re_results('\t', '\W+', 'Preceding 123:;[]\\:the rest') 
''

答案 1 :(得分:0)

re.findall是搜索模式的多个实例的好方法:

r = re.compile("^[^:]*:(.*)$", re.MULTILINE)
r.findall("a: b\nc: d")

答案 2 :(得分:0)

这是您想要的单行代码。功能编程真的很棒。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re

if __name__ == '__main__':

    findme= 'abc'
    sep = ','
    stringa = '1,2,3,4,5,abc'


    print map(lambda line, findme=findme, sep=sep: line.split(sep, 1)[1].strip() if re.search(findme, line) else "", stringa.split('\n'))

答案 3 :(得分:0)

您正在寻找的一个班轮是:

return re.findall(r'Preceeding\ Text:(.*)$', text) or ''

如果没有匹配项,findall()将返回一个空列表,在这种情况下,您希望结果为'',这就是或将要执行的操作。

不要使用string作为变量名,它与内置字符串模块冲突。