如何匹配可能跨越多条线的字符串?

时间:2018-02-21 15:13:10

标签: python regex

我有一个文档,当转换为文本时,将电话号码分成多行,如下所示:

(xxx)-xxx-
xxxx

由于与我的项目有关的各种原因,我不能简单地加入这些行。

如果我知道phonenumber="(555)-555-5555"如何编译正则表达式,那么如果我运行它

(555)-555- 5555

会匹配吗?

**编辑

为了帮助澄清我的问题,这是一个更抽象的形式。

test_string = "xxxx xx x xxxx"
text = """xxxx xx
x
xxxx"""

我需要在文本中找到测试字符串。新行可以在文本中的任何位置,并且应该考虑需要转义的字符。

3 个答案:

答案 0 :(得分:1)

您可以搜索字符串中可能存在的\n

import re
nums = ["(555)-555-\n5555", "(555)-555-5555"]
new_nums = [i for i in nums if re.findall('\([\d\n]+\)[\n-][\d\n]+-[\d\n]+', i)]

输出:

['(555)-555-\n5555', '(555)-555-5555']

答案 1 :(得分:1)

一个简单的解决方法是在搜索之前替换文档文本中的所有\n个字符:

pat = re.compile(r'\(\d{3}\)-\d{3}\d{4}')
numbers = pat.findall(text.replace('\n',''))

# ['(555)-555-5555']

如果由于任何原因无法做到这一点,那么明显的答案虽然难看,但却是处理每个搜索字符之间的换行符:

pat = re.compile(r'\(\n*5\n*5\n*5\n*\)\n*-\n*5\n*5\n*5\n*-\n*5\n*5\n*5\n*5')

如果您需要处理任何格式,可以填写如下格式:

phonenumber = '(555)-555-5555'
pat = re.compile('\n*'.join(['\\'+i if not i.isalnum() else i for i in phonenumber]))

# pat 
# re.compile(r'\(\n*5\n*5\n*5\n*\)\n*\-\n*5\n*5\n*5\n*\-\n*5\n*5\n*5\n*5', re.UNICODE)

测试用例:

import random
def rndinsert(s):
    i = random.randrange(len(s)-1)
    return s[:i] + '\n' + s[i:]

for i in range(10):
    print(pat.findall(rndinsert('abc (555)-555-5555 def')))

# ['(555)-555-5555']
# ['(555)-5\n55-5555']
# ['(555)-5\n55-5555']
# ['(555)-555-5555']
# ['(555\n)-555-5555']
# ['(5\n55)-555-5555']
# ['(555)\n-555-5555']
# ['(555)-\n555-5555']
# ['(\n555)-555-5555']
# ['(555)-555-555\n5']

答案 2 :(得分:0)

data = ["(555)-555-\n5555", "(55\n5)-555-\n55\n55", "(555\n)-555-\n5555", "(555)-555-5555"]

input = '(555)-555-5555'
#add new lines to input string
input = re.sub(r'(?!^|$)', r'\\n*', input)
#escape brackets ()
input = re.sub(r'(?=[()])', r'\\',input)

r = re.compile(input)

match = filter(r.match, data)

Code demo