如何根据条件将字符串与前一个字符串组合?
How to combine string with the previous one based on condition?
我有一个消息文本文件,格式为:
with open(code_path) as f:
contents = f.readlines()
print(contents)
['22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2\n',
'message2 continues\n',
'22/05/2022, 22.09 – Name: message3\n']
目前我有字符串形式的消息。一些长消息被分成两部分。我想要一个包含所有消息的消息列表(从日期开始)。
这就是我想要的:
['22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2 + message2 continues\n',
'22/05/2022, 22.09 – Name: message3\n']
有办法吗?
我找到了以以下日期开头的字符串:
import re
dates = [re.findall("^[0-3][0-9]/[0-3][0-9]/20[1-2][1-9]", i) for i in contents]
但是我不知道如何继续。
一个基本的方法是使用一种缓存:通过这些行,
- 如果该行以日期开头,则将新项目追加到缓存
- 如果没有,请附加到最新的项目。
messages = []
for line in contents:
if re.match(r'\d{2}/\d{2}/\d{4},\s+', line):
messages.append([line])
else:
messages[-1].append(line)
# messages
[['22/05/2022, 21.58 - Name: message1 \n'],
['22/05/2022, 22.07 – Name2: message2\n', 'message2 continues\n'],
['22/05/2022, 22.09 – Name: message3\n']]
然后您可以 join
他们(例如 [''.join(m) for m in messages]
)。或者,也可以直接构建字符串,但也许您想在某些时候区分 primary/following 行,那么列表更有用。
您也可以阅读所有行,然后匹配以类似日期模式开头的行,然后匹配所有不以类似日期模式开头的行。
使用更具体的日期,例如模式:
import re
with open("file") as f:
pattern = r"^(?:0[1-9]|[12][0-9]|3[01])/(?:0[1-9]|1[012])/\d{4},.*(?:\n(?!(?:0[1-9]|[12][0-9]|3[01])/(?:0[1-9]|1[012])/\d{4},).*)*"
print(re.findall(pattern, f.read(), re.M))
输出
[
'22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2\n\nmessage2 continues\n',
'22/05/2022, 22.09 – Name: message3\n'
]
模式不太精确,但有点短:
^\d{2}/\d{2}/\d{4},.*(?:\n(?!\d{2}/\d{2}/\d{4},).*)*
说明
^
字符串锚点的开始
\d{2}/\d{2}/\d{4},
匹配后跟逗号的类似日期的模式
.*
匹配行的其余部分
(?:
非捕获组作为一个整体重复
\n
匹配一个换行符
(?!\d{2}/\d{2}/\d{4},)
.*
匹配行的其余部分
)*
关闭非捕获组并可选择重复以匹配所有行
例子
import re
with open("file") as f:
pattern = r"^\d{2}/\d{2}/\d{4},.*(?:\n(?!\d{2}/\d{2}/\d{4},).*)*"
print(re.findall(pattern, f.read(), re.M))
我有一个消息文本文件,格式为:
with open(code_path) as f:
contents = f.readlines()
print(contents)
['22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2\n',
'message2 continues\n',
'22/05/2022, 22.09 – Name: message3\n']
目前我有字符串形式的消息。一些长消息被分成两部分。我想要一个包含所有消息的消息列表(从日期开始)。
这就是我想要的:
['22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2 + message2 continues\n',
'22/05/2022, 22.09 – Name: message3\n']
有办法吗?
我找到了以以下日期开头的字符串:
import re
dates = [re.findall("^[0-3][0-9]/[0-3][0-9]/20[1-2][1-9]", i) for i in contents]
但是我不知道如何继续。
一个基本的方法是使用一种缓存:通过这些行,
- 如果该行以日期开头,则将新项目追加到缓存
- 如果没有,请附加到最新的项目。
messages = []
for line in contents:
if re.match(r'\d{2}/\d{2}/\d{4},\s+', line):
messages.append([line])
else:
messages[-1].append(line)
# messages
[['22/05/2022, 21.58 - Name: message1 \n'],
['22/05/2022, 22.07 – Name2: message2\n', 'message2 continues\n'],
['22/05/2022, 22.09 – Name: message3\n']]
然后您可以 join
他们(例如 [''.join(m) for m in messages]
)。或者,也可以直接构建字符串,但也许您想在某些时候区分 primary/following 行,那么列表更有用。
您也可以阅读所有行,然后匹配以类似日期模式开头的行,然后匹配所有不以类似日期模式开头的行。
使用更具体的日期,例如模式:
import re
with open("file") as f:
pattern = r"^(?:0[1-9]|[12][0-9]|3[01])/(?:0[1-9]|1[012])/\d{4},.*(?:\n(?!(?:0[1-9]|[12][0-9]|3[01])/(?:0[1-9]|1[012])/\d{4},).*)*"
print(re.findall(pattern, f.read(), re.M))
输出
[
'22/05/2022, 21.58 - Name: message1 \n',
'22/05/2022, 22.07 – Name2: message2\n\nmessage2 continues\n',
'22/05/2022, 22.09 – Name: message3\n'
]
模式不太精确,但有点短:
^\d{2}/\d{2}/\d{4},.*(?:\n(?!\d{2}/\d{2}/\d{4},).*)*
说明
^
字符串锚点的开始\d{2}/\d{2}/\d{4},
匹配后跟逗号的类似日期的模式.*
匹配行的其余部分(?:
非捕获组作为一个整体重复\n
匹配一个换行符(?!\d{2}/\d{2}/\d{4},)
.*
匹配行的其余部分
)*
关闭非捕获组并可选择重复以匹配所有行
例子
import re
with open("file") as f:
pattern = r"^\d{2}/\d{2}/\d{4},.*(?:\n(?!\d{2}/\d{2}/\d{4},).*)*"
print(re.findall(pattern, f.read(), re.M))