正则表达式以一行中的CAPITAL词开始和结束,在CAPITAL单行词中的多行

时间:2019-07-19 05:33:44

标签: python regex

我想知道以下情况的正则表达式:

该字符串在单行中包含一个大写单词,之前有两个换行符。之后,会有几行字母数字字母(可能是非ASCII utf-8)或空行。我想捕获整个部分,从一行中的大写单词开始,到下一个大写单词行之前结束。单行大写单词可能重复。

我进行了探索,抬头很多,但失败了。

示例

ASDF
wqer rtre 34 $^&% fsfa
DDwrgd 43 er 1. ewrtfg
324rfegf 4gfgre

PIIPUU
gre tt HKH rre345 
sdrfetre
ewrewrqwr werfewrt34vds

ret
gre
wretretertettre

PIIPUU
asdf reb dsfdsg
dsafdfbh rt3456 rge grefgreg
reretr erfret34 ef

retretretr

QWE
pritoy Fbhfg 45345 )*9
tret 345 gret54
retre 56 gre ger
retgrh 546ttre

MMNNBMB
aserew Sfjlkjf
gdf
rerettyrdfv re HFGHFFHF er
ergre ret retre 
ret retretret 

reg regrtgh rertgre tret

我想将所有符合条件的部分分开,例如波纹管:

ASDF
wqer rtre 34 $^&% fsfa
DDwrgd 43 er 1. ewrtfg
324rfegf 4gfgre
PIIPUU
gre tt HKH rre345 
sdrfetre
ewrewrqwr werfewrt34vds

ret
gre
wretretertettre
PIIPUU
asdf reb dsfdsg
dsafdfbh rt3456 rge grefgreg
reretr erfret34 ef

retretretr
QWE
pritoy Fbhfg 45345 )*9
tret 345 gret54
retre 56 gre ger
retgrh 546ttre
MMNNBMB
aserew Sfjlkjf
gdf
rerettyrdfv re HFGHFFHF er
ergre ret retre 
ret retretret 

reg regrtgh rertgre tret

3 个答案:

答案 0 :(得分:4)

这是使用re.findall的一种方法:

matches = re.findall(r'(?:^|\n\n)([A-Z]{3,}.*?)(?=\n\n[A-Z]{3,}\n|$)', input, flags=re.DOTALL)
print(matches)

此打印:

['ASDF\nwqer rtre 34 $^&% fsfa\nDDwrgd 43 er 1. ewrtfg\n324rfegf 4gfgre',
 'QWE\npritoy Fbhfg 45345 )*9\ntret 345 gret54\nretre 56 gre ger\nretgrh 546ttre',
 'PIIPUU\ngre tt HKH rre345 \nsdrfetre\newrewrqwr werfewrt34vds\n\nret\ngre\nwretretertettre',
 'MMNNBMB\naserew Sfjlkjf\ngdf\nrerettyrdfv re HFGHFFHF er\nergre ret retre \nret retretret \n\nreg regrtgh rertgre tret']

以下是正则表达式模式的使用说明:

(?:^|\n\n)      match either the start of the input or two consecutive newlines
([A-Z]{3,}.*?)  then match and capture three or more capital letters,
                followed by all content (including newlines) until seeing
(?=\n\n[A-Z]{3,}\n|$)  either two newlines and a capital term or the end of the input

答案 1 :(得分:3)

尝试一下:

regex = re.compile(r"^[A-Z]+\r?\n(?:(?!^\r?\n[A-Z]+\r?\n).)*", re.MULTILINE|re.DOTALL)

说明:

^                      # Start of line
[A-Z]+                 # Match uppercase ASCII keyword
\r?\n                  # Match newline
(?:                    # Start of non-capturing group
 (?!^\r?\n[A-Z]+\r?\n) # Make sure we're not (yet) at the start of another keyword
 .                     # If so, match any character including newline
)*                     # Repeat any number of times.

测试live on regex101.com

答案 2 :(得分:3)

此表达式可能会提取我们期望的输出:

(?=^[A-Z]+$)([\s\S]*?)(?=^[A-Z]+$)|([\s\S]*)

如果要浏览/简化/修改该表达式,请在this demo的右上角进行解释。

测试

import re

regex = r"(?=^[A-Z]+$)([\s\S]*?)(?=^[A-Z]+$)|([\s\S]*)"

test_str = """

ASDF
wqer rtre 34 $^&% fsfa
DDwrgd 43 er 1. ewrtfg
324rfegf 4gfgre

QWE
pritoy Fbhfg 45345 )*9
tret 345 gret54
retre 56 gre ger
retgrh 546ttre

PIIPUU
gre tt HKH rre345 
sdrfetre
ewrewrqwr werfewrt34vds

ret
gre
wretretertettre

MMNNBMB
aserew Sfjlkjf
gdf
rerettyrdfv re HFGHFFHF er
ergre ret retre 
ret retretret 

reg regrtgh rertgre tret

"""

print(re.findall(regex, test_str, re.MULTILINE))

输出

[('', ''), ('ASDF\nwqer rtre 34 $^&% fsfa\nDDwrgd 43 er 1. ewrtfg\n324rfegf 4gfgre\n\n', ''), ('', ''), ('QWE\npritoy Fbhfg 45345 )*9\ntret 345 gret54\nretre 56 gre ger\nretgrh 546ttre\n\n', ''), ('', ''), ('PIIPUU\ngre tt HKH rre345 \nsdrfetre\newrewrqwr werfewrt34vds\n\nret\ngre\nwretretertettre\n\n', ''), ('', ''), ('', 'MMNNBMB\naserew Sfjlkjf\ngdf\nrerettyrdfv re HFGHFFHF er\nergre ret retre \nret retretret \n\nreg regrtgh rertgre tret'), ('', '')]