使用正则表达式、循环、枚举解析复杂的字符串列表,以生成 pandas 数据帧
Parsing complicated list of strings using regex, loops, enumerate, to produce a pandas dataframe
我有一长串很多元素,每个元素都是一个字符串。请参阅以下示例:
data = ['BAT.A.100', 'Regulation 2020-1233', 'this is the core text of', 'the regulation referenced ',
'MOC to BAT.A.100', 'this', 'is', 'one method of demonstrating compliance to BAT.A.100',
'BAT.A.120', 'Regulation 2020-1599', 'core text of the regulation ...', ' more free text','more free text',
'BAT.A.145', 'Regulation 2019-3333', 'core text of' ,'the regulation1111',
'MOC to BAT.A.145', 'here is how you can show compliance to BAT.A.145','more free text',
'MOC2 to BAT.A.145', ' here is yet another way of achieving compliance']
我想要的输出最终是一个 Pandas DataFrame,如下所示:
由于可能需要连接字符串,我首先使用 ##
将所有元素连接到单个字符串以分隔已连接的文本。
我要使用所有正则表达式,因为否则会有很多条件需要检查。
re_req = re.compile(r'##(?P<Short_ref>BAT\.A\.\d{3})'
r'##(?P<Full_Reg_ref>Regulation\s\d{4}-\d{4})'
r'##(?P<Reg_text>.*?MOC to |.*?(?=##BAT\.A\.\d{3})(?!))'
r'(?:##)?(?:(?P<Moc_text>.*?MOC2 to )(?P<MOC2>(?:##)?.*?(?=##BAT\.A\.\d{3})(?!)|.+)'
r'|(?P<Moc_text_temp>.*?(?=##BAT\.A\.\d{3})(?!)))')
final_list = []
for match in re_req.finditer("##" + "##".join(data)):
inner_list = [match.group('Short_ref').replace("##", " "),
match.group('Full_Reg_ref').replace("##", " "),
match.group('Reg_text').replace("##", " ")]
if match.group('Moc_text_temp'): # just Moc_text is present
inner_list += [match.group('Moc_text_temp').replace("##", " "), ""]
elif match.group('Moc_text') and match.group('MOC2'): # both Mock_text and MOC2 is present
inner_list += [match.group('Moc_text').replace("##", " "), match.group('MOC2').replace("##", " ")]
else: # neither Moc_text nor MOC2 is present
inner_list += ["", ""]
final_list.append(inner_list)
final_df = pd.DataFrame(final_list, columns=['Short_ref', 'Full_Reg_ref', 'Reg_text', 'Moc_text', 'MOC2'])
正则表达式的第一行和第二行与您之前发布的相同,并标识了前两列。
在正则表达式的第三行,r'##(?P<Reg_text>.*?MOC to |.*?(?=##BAT\.A\.\d{3})(?!))'
- 将 MOC 之前的所有文本匹配到 Short_ref 或匹配下一个 Reg_text 之前的所有文本。 (?=##BAT\.A\.\d{3})(?!)
部分是将文本变为 Short_ref
模式,如果 Short_ref
不是当前的 Reg_text。
第四行是针对 Moc_text
和 MOC2
都存在的情况,or
第五行是针对仅存在 Moc_text
的情况。这部分正则表达式与第三行类似。
最后使用 finditer
遍历所有匹配项并构建数据帧的行
final_df
:
我有一长串很多元素,每个元素都是一个字符串。请参阅以下示例:
data = ['BAT.A.100', 'Regulation 2020-1233', 'this is the core text of', 'the regulation referenced ',
'MOC to BAT.A.100', 'this', 'is', 'one method of demonstrating compliance to BAT.A.100',
'BAT.A.120', 'Regulation 2020-1599', 'core text of the regulation ...', ' more free text','more free text',
'BAT.A.145', 'Regulation 2019-3333', 'core text of' ,'the regulation1111',
'MOC to BAT.A.145', 'here is how you can show compliance to BAT.A.145','more free text',
'MOC2 to BAT.A.145', ' here is yet another way of achieving compliance']
我想要的输出最终是一个 Pandas DataFrame,如下所示:
由于可能需要连接字符串,我首先使用 ##
将所有元素连接到单个字符串以分隔已连接的文本。
我要使用所有正则表达式,因为否则会有很多条件需要检查。
re_req = re.compile(r'##(?P<Short_ref>BAT\.A\.\d{3})'
r'##(?P<Full_Reg_ref>Regulation\s\d{4}-\d{4})'
r'##(?P<Reg_text>.*?MOC to |.*?(?=##BAT\.A\.\d{3})(?!))'
r'(?:##)?(?:(?P<Moc_text>.*?MOC2 to )(?P<MOC2>(?:##)?.*?(?=##BAT\.A\.\d{3})(?!)|.+)'
r'|(?P<Moc_text_temp>.*?(?=##BAT\.A\.\d{3})(?!)))')
final_list = []
for match in re_req.finditer("##" + "##".join(data)):
inner_list = [match.group('Short_ref').replace("##", " "),
match.group('Full_Reg_ref').replace("##", " "),
match.group('Reg_text').replace("##", " ")]
if match.group('Moc_text_temp'): # just Moc_text is present
inner_list += [match.group('Moc_text_temp').replace("##", " "), ""]
elif match.group('Moc_text') and match.group('MOC2'): # both Mock_text and MOC2 is present
inner_list += [match.group('Moc_text').replace("##", " "), match.group('MOC2').replace("##", " ")]
else: # neither Moc_text nor MOC2 is present
inner_list += ["", ""]
final_list.append(inner_list)
final_df = pd.DataFrame(final_list, columns=['Short_ref', 'Full_Reg_ref', 'Reg_text', 'Moc_text', 'MOC2'])
正则表达式的第一行和第二行与您之前发布的相同,并标识了前两列。
在正则表达式的第三行,r'##(?P<Reg_text>.*?MOC to |.*?(?=##BAT\.A\.\d{3})(?!))'
- 将 MOC 之前的所有文本匹配到 Short_ref 或匹配下一个 Reg_text 之前的所有文本。 (?=##BAT\.A\.\d{3})(?!)
部分是将文本变为 Short_ref
模式,如果 Short_ref
不是当前的 Reg_text。
第四行是针对 Moc_text
和 MOC2
都存在的情况,or
第五行是针对仅存在 Moc_text
的情况。这部分正则表达式与第三行类似。
最后使用 finditer
遍历所有匹配项并构建数据帧的行
final_df
: