我有这个正则表达式:^:([^:]+):([^:]*)
,就像在this regex101 link中一样。
现在,在Python中,我有这个:
def get_data():
data = read_mt_file()
match_fields = re.compile('^:([^:]+):([^:]*)', re.MULTILINE)
fields = re.findall(match_fields, data)
return fields
对于包含regex101数据的文件,返回:
[('1', 'text\ntext\n\n'), ('20', 'text\n\n'), ('21', 'text\ntext\ntext\n\n'), ('22', ' \n\n'), ('25', 'aa\naa\naaaaa')]
现在,这没关系,但我想更改正则表达式,以便我可以根据行数来获得组的数量。含义:
1
text\ntext\n\n
我想改为:
1
text\n
),(text\n\n
))< - 这些应该以某种方式存在于同一个组中但是分开,每个都在他自己的子组中。不知怎的,我需要知道它们都属于1
字段,但是是sepparate lines。所以,在python中,该文件的所需结果是:
[('1', '(text\n), (text\n\n)'), ('20', 'text\n\n'), ('21', '(text\n), (text\n), (text\n\n)'), ('22', ' \n\n'), ('25', '(aa\n), (aa\n), (aaaaa)')]
正则表达式可以实现吗?这可以通过一些不错的字符串操作来实现吗?
答案 0 :(得分:0)
要做你想做的事,你需要另一个正则表达式。
这是因为re.match
仅匹配它匹配的最后一项:
>>> re.match(r'(\d)+', '12345').groups()
('5',)
而不是使用一个正则表达式,你需要使用两个。
您正在使用的那个,然后使用re.findall
来匹配所有“子组”。
您可以通过简单匹配非\n
的任何内容以及任意数量的\n
来获取这些子组。
因此,您可以使用[^\n]+\n*
:
>>> re.findall(r'[^\n]+\n*', 'text\ntext')
['text\n', 'text']
>>> re.findall(r'[^\n]+\n*', 'text\ntext\n\n')
['text\n', 'text\n\n']
>>> re.findall(r'[^\n]+\n*', '')
[]
答案 1 :(得分:0)
您可以使用一个简单的技巧:在与正则表达式匹配后,对第2组值运行dotXpos = [?] * screenXpixels;
dotYpos = [?] * screenYpixels;
正则表达式:
.+\n*
在这里,
import re
p = re.compile(r'^:([^:]+):([^:]+)', re.MULTILINE)
s = ":1:text\ntext\n\n:20:text\n\n:21:text\ntext\ntext\n\n:22: \n\n:25:aa\naa\naaaaa"
print([[x.group(1)] + re.findall(r".+\n*", x.group(2)) for x in p.finditer(s)])
使用您的正则表达式p.finditer(s)
- 根据第一组内容创建的列表[x.group(1)]
- 从第2组内容中获取单个行(使用尾随换行符,0或更多)re.findall(r".+\n*", x.group(2))
- 将列表合并为1。结果是
[] + re.findall
另一种方法:将所有子字符串与您的模式匹配,然后使用[['1', 'text\n', 'text\n\n'], ['20', 'text\n\n'], ['21', 'text\n', 'text\n', 'text\n\n'], ['22', ' \n\n'], ['25', 'aa\n', 'aa\n', 'aaaaa']]
在以可选换行符结尾的行之间添加re.sub
:
), (
结果:
[(x, "({})".format(re.sub(r".+(?!\n*$)\n+", r"\g<0>), (", y))) for x, y in p.findall(s)]
下面:
[('1', '(text\n), (text\n\n)'), ('20', '(text\n\n)'), ('21', '(text\n), (text\n), (text\n\n)'), ('22', '( \n\n)'), ('25', '(aa\n), (aa\n), (aaaaa)')]
- 使用正则表达式以包含捕获组内容的元组列表的形式抓取所有匹配项p.findall(s)
- 从第1组内容和第2组内容创建一个元组,使用下面描述的方式(x, "({})".format(re.sub(r".+(?!\n*$)\n+", r"\g<0>), (", y)))
进行一点修改re.sub
- 匹配换行符以外的1 +个字符的模式,如果它们不在字符串的末尾,则匹配1 +换行符号。如果它们位于字符串的末尾,则不会进行替换(最后避免.+(?!\n*$)\n+
)。替换字符串中的, ()
将整个匹配重新插入到结果字符串中,并将\g<0>
附加到其中。