正则表达式匹配多列表元素的规则调整需求问询
解决方案
针对你的两个规则调整需求,我们需要结合正则表达式与代码逻辑来实现(纯正则无法单独完成所有约束,尤其是list1元素去重),具体方案如下:
核心思路
- list1与list2连续匹配:用正则捕获文本中所有
list1元素 + 空格 + list2元素的连续组合 - list3任意位置匹配:单独捕获文本中所有list3的元素,后续与合法的连续对组合
- list1元素去重:通过代码跟踪已匹配的list1元素,仅保留每个list1元素第一次出现的连续对
实现代码
import pandas as pd import re # 输入示例DataFrame df = pd.DataFrame({'text': [ 'zzz zzz chest bike zz zz day zzz', 'zzz zz west like say zz zzz west bike zzz lay zzz zz zz nest mike zzz' ]}) def process_text(text): # 定义目标列表 list_1 = ['chest', 'test', 'west', 'nest'] list_2 = ['mike', 'bike', 'like', 'pike'] list_3 = ['hay', 'day', 'may', 'say'] # 构建各列表的正则匹配串 list1_pattern = '|'.join(list_1) list2_pattern = '|'.join(list_2) list3_pattern = '|'.join(list_3) # 匹配list1与list2的连续对,捕获两个分组 pair_matches = re.finditer(rf'\b(?P<match_1>{list1_pattern})\s+(?P<match_2>{list2_pattern})\b', text) # 过滤重复的list1元素,保留首次出现的连续对 seen_list1 = set() valid_pairs = [] for match in pair_matches: match1_val = match.group('match_1') if match1_val not in seen_list1: seen_list1.add(match1_val) valid_pairs.append( (match1_val, match.group('match_2')) ) # 捕获文本中所有list3元素(可选去重) list3_matches = list(set(re.findall(rf'\b({list3_pattern})\b', text))) # 生成最终匹配结果 result_rows = [] if not list3_matches: # 无list3元素时,仅保留连续对 for pair in valid_pairs: result_rows.append( (pair[0], pair[1], None) ) else: # 每个合法连续对与每个list3元素组合成新行 for pair in valid_pairs: for l3_val in list3_matches: result_rows.append( (pair[0], pair[1], l3_val) ) return result_rows # 应用处理函数并展开结果到多行 df['matches'] = df['text'].apply(process_text) expanded_df = df.explode('matches').reset_index(drop=True) expanded_df[['match_1', 'match_2', 'match_3']] = pd.DataFrame(expanded_df['matches'].tolist(), index=expanded_df.index) expanded_df = expanded_df.drop('matches', axis=1) # 输出结果 print(expanded_df)
关键说明
- 连续匹配正则:
rf'\b(?P<match_1>{list1_pattern})\s+(?P<match_2>{list2_pattern})\b'确保list1与list2元素以空格分隔且为完整单词(\b匹配单词边界) - list3匹配正则:
rf'\b({list3_pattern})\b'捕获文本中任意位置的list3完整单词 - 去重逻辑:通过
seen_list1集合记录已匹配的list1元素,跳过后续重复的list1条目,满足需求2的约束
测试结果
针对你的示例文本,输出结果如下:
- 第一个文本输出:
| text | match_1 | match_2 | match_3 |
|---|---|---|---|
| zzz zzz chest bike zz zz day zzz | chest | bike | day |
- 第二个文本输出:
| text | match_1 | match_2 | match_3 |
|---|---|---|---|
| zzz zz west like say zz zzz west bike zzz lay zzz zz zz nest mike zzz | west | like | say |
| zzz zz west like say zz zzz west bike zzz lay zzz zz zz nest mike zzz | nest | mike | say |
内容的提问来源于stack exchange,提问作者user22391597
相关产品推荐
相关产品推荐

