正则表达式结合了 2 行完整的呼叫数据
Regex combining 2 complete lines of call data
我正在准备一个 python 脚本,它只是根据用户输入的 phone 号码从 .txt 日志文件中获取通话记录。
我需要帮助编写一个捕获每个调用日志的正则表达式,以便它可以“拆分”到列表中。
每个日志都以字母开头,例如(长,北,南,东)。
在每个日志的开头是一个以“T”开头的时间戳。示例:T 02/25 00:00
以 (N,S,E) 开头的记录需要包含第二行。或者,(L) 记录没有,但它们确实有一个空的 space 下面可以包含。
本质上,我需要的是每条以 (L,N,S,E) 开头的记录及其下方的一行。
请参阅下面的通话记录示例
T 02/25 00:00
L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000
N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630
& 0000 0000
S 067 00 00984 T000134 02/25 08:06 00:00:02 A 61445
& 0000 0000
S 068 00 T000002 29536 02/25 08:05 00:00:36
& 0000 0000 1234567890XXXXXX
E 069 00 T000002 T000185 02/25 08:06 00:00:00
& 0000 0000 1234567890XXXXXX
例如:
L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000
将是一场比赛并且
N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630
& 0000 0000
会是另一个,
S 068 00 T000002 29536 02/25 08:05 00:00:36
& 0000 0000 1234567890XXXXXX
会是另一个,依此类推...
我的正则表达式知识有限,但这是我到目前为止想出的。
N(.*)\n(.*)
这会选择以“N”开头的每条记录的第一行和第二行,但会将它们放在不同的组中。任何方向表示赞赏。
要匹配这 4 个字符中的任何一个,您可以使用字符 class [LNSE]
后跟 space 和该行的其余部分。
然后在同一捕获组中使用可选部分来匹配换行符和该行的其余部分(如果它不以任何这些字符开头)。
这也允许只匹配一行。
^[LNSE] (.*(?:\n(?![LNSE] ).*)?)
^
字符串开头
[LNSE]
匹配任何列出的字符和 space
(
捕获 组 1
.*
匹配行的其余部分
(?:
非捕获组
\n(?![LNSE] ).*
如果换行符不以任何列出的字符开头,则使用否定先行匹配换行符和该行的其余部分
)?
关闭非捕获组并使其可选
)
关闭非捕获组
看到一个regex demo and a Python demo.
如果你想匹配 0 或更多行,你 can change ?
到 *
零次或多次重复。
如果要匹配整行包括前导字符,可以省略捕获组,直接得到the match.
例如,在读取整个文件时使用re.findall获取捕获组1的值:
import re
with open('file.log', 'r') as file:
regex = r"^[LNSE] (.*(?:\n(?![LNSE] ).*)*)"
print(re.findall(regex, file.read(), re.MULTILINE))
这是另一种不用正则表达式的方法:
data = []
with open('file.log', 'r') as f:
next(f)
for line in f:
if line[0] in ("L", "N", "S", "E"):
data.append(line)
else:
data[-1] += line
print(data)
next(f)
用于跳过第一行(T 02/25 00:00
)。
假设所有日志都是两行,也可以使用列表理解:
with open('file.log', 'r') as f:
next(f)
lines = f.readlines()
data = [''.join(lines[i:i+2]) for i in range(0, len(lines), 2)]
print(data)
每一行都存储在一个列表中lines
(第一行除外,已被跳过)。列表理解然后将列表中的元素两个两个地连接起来。
如果日志文件存储在变量中,则相同:
lines = text.split("\n")[1:] # [-1:] to skip the first line
data = [''.join(lines[i:i+2]) for i in range(0, len(lines), 2)]
print(data)
输出:
[
'L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000\n \n',
'N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630\n& 0000 0000 \n',
'S 067 00 00984 T000134 02/25 08:06 00:00:02 A 61445\n& 0000 0000 \n',
'S 068 00 T000002 29536 02/25 08:05 00:00:36 \n& 0000 0000 1234567890XXXXXX \n',
'E 069 00 T000002 T000185 02/25 08:06 00:00:00 \n& 0000 0000 1234567890XXXXXX'
]
我正在准备一个 python 脚本,它只是根据用户输入的 phone 号码从 .txt 日志文件中获取通话记录。
我需要帮助编写一个捕获每个调用日志的正则表达式,以便它可以“拆分”到列表中。
每个日志都以字母开头,例如(长,北,南,东)。
在每个日志的开头是一个以“T”开头的时间戳。示例:T 02/25 00:00
以 (N,S,E) 开头的记录需要包含第二行。或者,(L) 记录没有,但它们确实有一个空的 space 下面可以包含。
本质上,我需要的是每条以 (L,N,S,E) 开头的记录及其下方的一行。
请参阅下面的通话记录示例
T 02/25 00:00 L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000 N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630 & 0000 0000 S 067 00 00984 T000134 02/25 08:06 00:00:02 A 61445 & 0000 0000 S 068 00 T000002 29536 02/25 08:05 00:00:36 & 0000 0000 1234567890XXXXXX E 069 00 T000002 T000185 02/25 08:06 00:00:00 & 0000 0000 1234567890XXXXXX
例如:
L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000
将是一场比赛并且
N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630 & 0000 0000
会是另一个,
S 068 00 T000002 29536 02/25 08:05 00:00:36 & 0000 0000 1234567890XXXXXX
会是另一个,依此类推...
我的正则表达式知识有限,但这是我到目前为止想出的。
N(.*)\n(.*)
这会选择以“N”开头的每条记录的第一行和第二行,但会将它们放在不同的组中。任何方向表示赞赏。
要匹配这 4 个字符中的任何一个,您可以使用字符 class [LNSE]
后跟 space 和该行的其余部分。
然后在同一捕获组中使用可选部分来匹配换行符和该行的其余部分(如果它不以任何这些字符开头)。
这也允许只匹配一行。
^[LNSE] (.*(?:\n(?![LNSE] ).*)?)
^
字符串开头[LNSE]
匹配任何列出的字符和 space(
捕获 组 1.*
匹配行的其余部分(?:
非捕获组\n(?![LNSE] ).*
如果换行符不以任何列出的字符开头,则使用否定先行匹配换行符和该行的其余部分
)?
关闭非捕获组并使其可选
)
关闭非捕获组
看到一个regex demo and a Python demo.
如果你想匹配 0 或更多行,你 can change
?
到*
零次或多次重复。如果要匹配整行包括前导字符,可以省略捕获组,直接得到the match.
例如,在读取整个文件时使用re.findall获取捕获组1的值:
import re
with open('file.log', 'r') as file:
regex = r"^[LNSE] (.*(?:\n(?![LNSE] ).*)*)"
print(re.findall(regex, file.read(), re.MULTILINE))
这是另一种不用正则表达式的方法:
data = []
with open('file.log', 'r') as f:
next(f)
for line in f:
if line[0] in ("L", "N", "S", "E"):
data.append(line)
else:
data[-1] += line
print(data)
next(f)
用于跳过第一行(T 02/25 00:00
)。
假设所有日志都是两行,也可以使用列表理解:
with open('file.log', 'r') as f:
next(f)
lines = f.readlines()
data = [''.join(lines[i:i+2]) for i in range(0, len(lines), 2)]
print(data)
每一行都存储在一个列表中lines
(第一行除外,已被跳过)。列表理解然后将列表中的元素两个两个地连接起来。
如果日志文件存储在变量中,则相同:
lines = text.split("\n")[1:] # [-1:] to skip the first line
data = [''.join(lines[i:i+2]) for i in range(0, len(lines), 2)]
print(data)
输出:
[
'L 065 00 24329 12313 244.0.15.55 252.9.11.90 02/25 08:05 00:00:44 0000 0000\n \n',
'N 066 00 23442 T000185 262.1.00.09 02/25 08:05 00:00:02 A 16630\n& 0000 0000 \n',
'S 067 00 00984 T000134 02/25 08:06 00:00:02 A 61445\n& 0000 0000 \n',
'S 068 00 T000002 29536 02/25 08:05 00:00:36 \n& 0000 0000 1234567890XXXXXX \n',
'E 069 00 T000002 T000185 02/25 08:06 00:00:00 \n& 0000 0000 1234567890XXXXXX'
]