Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用正则表达式捕获以单个分号开头的行之间的文本?_Python_Regex - Fatal编程技术网

Python 如何使用正则表达式捕获以单个分号开头的行之间的文本?

Python 如何使用正则表达式捕获以单个分号开头的行之间的文本?,python,regex,Python,Regex,我想捕获以单分号开头的行之间的文本: 样本输入: s = ''' ; the color blue ; the color green ; the color red ; ''' 这是所需的输出: ['the color blue', 'the color green', 'the color red'] 此尝试的解决方案不起作用: import re pat = r'^;(.*)^;' r = re.findall(pat, s, re.S|re.M) print(r) 这是

我想捕获以单分号开头的行之间的文本:

样本输入:

s = '''
;

the color blue

;

the color green

;

the color red

;
'''
这是所需的输出:

['the color blue', 'the color green', 'the color red']
此尝试的解决方案不起作用:

import re
pat = r'^;(.*)^;'
r = re.findall(pat, s, re.S|re.M)
print(r)
这是错误的输出:

['\n\nthe color blue\n\n;\n\nthe color green\n\n;\n\nthe color red\n\n']

非正则表达式解决方案,我在
上拆分并删除空字符串

s = '''
    ;

    the color blue


;

the color green

;

the color red

;
'''

f = s.split(';')


x = [a.strip('\n') for a in f]

print(x) #prints ['', 'the color blue', 'the color green', 'the color red', '']

a = [elem for elem in x if len(elem)]

print(a) #prints ['the color blue', 'the color green', 'the color red']

您可以将其作为模式:

pat = r';\n\n([\w* *]*)'

r = re.findall(pat, s)
这将捕获您需要的内容。

您可以使用
\s*(*?)\s*(?=;)
。用法:

print( re.findall(r'(?s);\s*(.*?)\s*(?=;)', s) )
# output: ['the color blue', 'the color green', 'the color red']

说明:

(?s)   # dot-all modifier (. matches newlines)
;      # consume a semicolon
\s*    # skip whitespace
(.*?)  # capture the following text, as little as possible, such that...
\s*    # ... it is followed only by (optional) whitespace, and...
(?=;)  # ... a semicolon

将其视为分隔符

(?sm)^\s*\r?\n(.*?\s*(?=^;\s*\r?\n)

解释

 (?sm)                         # Modifiers: dot-all, multi-line
 ^ ; \s* \r? \n                # Begining delimiter
 ( .*? )                       # (1), Text 
 \s*                           # Wsp trim
 (?= ^ ; \s* \r? \n )          # End delimiter

我知道这不是你要的。但值得考虑将pyparsing作为re的替代方案。实际上,pyparsing正确地包含regex。注意这个简单的解析器如何处理各种数量的空行

>>> parsifal = open('temp.txt').read()
>>> print (parsifal)


;

the colour blue
;
the colour green
;
the colour red
;
the colour purple




;

the colour magenta

;


>>> import pyparsing as pp
>>> p = pp.OneOrMore(pp.Suppress(';\n')+pp.ZeroOrMore(pp.Suppress('\n'))+pp.CharsNotIn(';\n')+pp.ZeroOrMore(pp.Suppress('\n')))
>>> p.parseString(parsifal)
(['the colour blue', 'the colour green', 'the colour red', 'the colour purple', 'the colour magenta'], {})

作为一个整体,解析器匹配一个或多个分号或新行序列,后跟除这些字符以外的任何字符和新行

\n\n
放在分号之后和捕获组之后我发现此正则表达式存在多个问题。1) 它依赖于每个分号后面有两个空行。2) 它只捕获一行文本,即它不会从
中获取
b
\n\na\nb
-事实上,
a
b
之间的任何非空格、非单词、非星号字符都会将其打断。3)
[\w**]
不会做你认为它会做的事情,它相当于
[\w\*]
。它捕获了他测试中的所有内容。你会推荐什么来代替
[\w**]
?请注意@Rawing的经文-我在他的教导中感受到智慧^^如果有人希望正则表达式能够捕获以一个分号开头的行与行之间的任何文本(包括带有任何字符的多行),并且没有空行,例如:
s='';第1项、第2项;[第3项]:第4项!项目5?(项目6);项目7:项目8;这是第一行这是第二行这是第三行确定--我仍然没有看到一个正则表达式能够捕获以单分号开头的行之间的文本,其中可能包括一行或多行以及任何字符,并且在以分号开头的行后面有零行或多行空行。对不起,我对原来的问题做了一些调整,以处理更广泛的可能性。谢谢这个正则表达式处理了我所想到的所有可能的变化——分隔符行后面的零行或多行空行、文本中的多行以及文本中的任何字符。感谢指向pyparsing的指针——我将探讨它。