如何从 python 中的文件的多行中提取子字符串
How can I extract a substring from multiple lines from a file in python
我有一个包含数千行的文件,在文件中,有一些行如下:
Line 115463: 08:59:25.106 08:59:24.992877 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event2f, DIR = 13) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 987
Line 236362: 08:59:28.647 08:59:28.597827 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventab, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 324964: 08:59:40.456 08:59:40.403644 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventac, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 341172: 08:59:40.659 08:59:40.616565 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventfb, DIR = 13) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 987
Line 373186: 08:59:41.174 08:59:41.104755 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event2f, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 480217: 08:59:44.481 08:59:44.389453 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventx1, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 505424: 08:59:44.777 08:59:44.701709 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event1a, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
我只需要提取子串
'1a'
来自
'SNS__GENERATED_EVENTS (Event1a, DIR = 1)'
等等。
所以,基本上,'(Event'
之后的两个字符
我需要将它们存储在列表中或其他我可以使用它们的地方。
我该怎么做?
到目前为止,我已经尝试了以下代码,但它给了我一些混合的值:
events = []
for line in input_txt_file:
if "Ta-SNS__GENERATED_EVENTS " not in line: continue
parts = line.split('Event')
event_temp = [0]
for i,part in enumerate(parts):
if part.endswith("Ta-SNS__GENERATED_EVENTS ("): event_temp[0] = parts[i+1].split(None,1)[0].split(',',2)[0]
events.append(event_temp)
print events
我得到的输出是:
[[0], [0], ['2f'], ['2f'], ['ab'], ['ab'], [0], [0], ['ac'], ['ac'], ['fb'], .......]
如果您知道它始终处于那个位置,您可以简单地执行以下操作:
hexes = [line[99:101] for line in file]
如果有不包含该文本的行,您可以执行以下操作:
hexes = [line[99:101] for line in file if 'Ta-SNS__GENERATED_EVENTS' in line]
如果行位置始终固定,Wayne 的答案是最有效的。如果位置可以稍微变化,这是使用正则表达式的合适情况:
import re
events = []
for line in input_txt_file:
match = re.search(r'SNS__GENERATED_EVENTS.*?Event(..)', line)
if match:
events.append(match.group(1))
这将在每一行中搜索 SNS__GENERATED_EVENTS
,然后可能是一些字符,然后是 Event
,然后是另外两个字符,然后获取这两个字符。
我个人会使用 re
模块进行子字符串搜索。
import re
for line in input_txt_file:
val = ''
val = re.search('SNS__GENERATED_EVENTS \(Event(.+?), DIR\)', line).group(1)
print(val)
此处不需要正则表达式:只需根据 Ta-SNS__GENERATED_EVENTS (Event
进行拆分,如果有,则取第二个字段的 2 个首字母:
events=[]
for line in input_txt_file:
toks = line.split("Ta-SNS__GENERATED_EVENTS (Event")
if len(toks)>1:
events.append(toks[1][:2])
编辑:找到了一个很酷的单行等价物:
events=[tok[:2] for line in input_txt_file for i,tok in enumerate(line.split("Ta-SNS__GENERATED_EVENTS (Event")) if i==1]
使用enumerate
并测试拆分项目的索引是否为1:表示至少有2个项目。在这种情况下,从令牌中取出 2 个第一个字符。
EDIT2:Amber 更好地使用 partition
来避免 enumerate
黑客攻击:
events=[t for t in (l.partition("Ta-SNS__GENERATED_EVENTS (Event")[2] for l in input_txt_file) if t]
使用 re.findall()
函数的简短解决方案:
# change to your actual file path
with open('./text_files/events.txt', 'r') as fh:
l = re.findall(r'(?<=Ta-SNS__GENERATED_EVENTS \(Event)\w+', fh.read(), re.M)
print(l)
输出:
['2f', 'ab', 'ac', 'fb', '2f', 'x1', '1a']
我有一个包含数千行的文件,在文件中,有一些行如下:
Line 115463: 08:59:25.106 08:59:24.992877 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event2f, DIR = 13) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 987
Line 236362: 08:59:28.647 08:59:28.597827 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventab, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 324964: 08:59:40.456 08:59:40.403644 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventac, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 341172: 08:59:40.659 08:59:40.616565 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventfb, DIR = 13) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 987
Line 373186: 08:59:41.174 08:59:41.104755 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event2f, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 480217: 08:59:44.481 08:59:44.389453 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Eventx1, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
Line 505424: 08:59:44.777 08:59:44.701709 ASDF_IIS_CFGDB GenMod Ta-SNS__GENERATED_EVENTS (Event1a, DIR = 1) rrc_UlUtranMsg.c (../../../HEDGE/UL3/ASDF/UtranMsg/Uplink/Code/Src) 934
我只需要提取子串
'1a'
来自
'SNS__GENERATED_EVENTS (Event1a, DIR = 1)'
等等。 所以,基本上,'(Event'
之后的两个字符我需要将它们存储在列表中或其他我可以使用它们的地方。
我该怎么做?
到目前为止,我已经尝试了以下代码,但它给了我一些混合的值:
events = []
for line in input_txt_file:
if "Ta-SNS__GENERATED_EVENTS " not in line: continue
parts = line.split('Event')
event_temp = [0]
for i,part in enumerate(parts):
if part.endswith("Ta-SNS__GENERATED_EVENTS ("): event_temp[0] = parts[i+1].split(None,1)[0].split(',',2)[0]
events.append(event_temp)
print events
我得到的输出是:
[[0], [0], ['2f'], ['2f'], ['ab'], ['ab'], [0], [0], ['ac'], ['ac'], ['fb'], .......]
如果您知道它始终处于那个位置,您可以简单地执行以下操作:
hexes = [line[99:101] for line in file]
如果有不包含该文本的行,您可以执行以下操作:
hexes = [line[99:101] for line in file if 'Ta-SNS__GENERATED_EVENTS' in line]
如果行位置始终固定,Wayne 的答案是最有效的。如果位置可以稍微变化,这是使用正则表达式的合适情况:
import re
events = []
for line in input_txt_file:
match = re.search(r'SNS__GENERATED_EVENTS.*?Event(..)', line)
if match:
events.append(match.group(1))
这将在每一行中搜索 SNS__GENERATED_EVENTS
,然后可能是一些字符,然后是 Event
,然后是另外两个字符,然后获取这两个字符。
我个人会使用 re
模块进行子字符串搜索。
import re
for line in input_txt_file:
val = ''
val = re.search('SNS__GENERATED_EVENTS \(Event(.+?), DIR\)', line).group(1)
print(val)
此处不需要正则表达式:只需根据 Ta-SNS__GENERATED_EVENTS (Event
进行拆分,如果有,则取第二个字段的 2 个首字母:
events=[]
for line in input_txt_file:
toks = line.split("Ta-SNS__GENERATED_EVENTS (Event")
if len(toks)>1:
events.append(toks[1][:2])
编辑:找到了一个很酷的单行等价物:
events=[tok[:2] for line in input_txt_file for i,tok in enumerate(line.split("Ta-SNS__GENERATED_EVENTS (Event")) if i==1]
使用enumerate
并测试拆分项目的索引是否为1:表示至少有2个项目。在这种情况下,从令牌中取出 2 个第一个字符。
EDIT2:Amber 更好地使用 partition
来避免 enumerate
黑客攻击:
events=[t for t in (l.partition("Ta-SNS__GENERATED_EVENTS (Event")[2] for l in input_txt_file) if t]
使用 re.findall()
函数的简短解决方案:
# change to your actual file path
with open('./text_files/events.txt', 'r') as fh:
l = re.findall(r'(?<=Ta-SNS__GENERATED_EVENTS \(Event)\w+', fh.read(), re.M)
print(l)
输出:
['2f', 'ab', 'ac', 'fb', '2f', 'x1', '1a']