python - python 正则表达式在某些关键字之后查找第一个单词
问题描述
我有以下 python 代码在某些关键字之后检索第一个单词:
file_tokens = ('DATABASE', 'EXTERNAL_FILE', 'FILE', 'FILENAME', 'INCLUDE')
# match newline, only spaces, then exact token, then spaces, then everything but whitespace
search_pattern = r'\n\s*({})\s+([^\s]*)'.format('|'.join(file_tokens))
matches = re.findall(search_pattern, file_content_string, flags=re.IGNORECASE) # find matches
它在如下字符串中运行良好(包括换行符和回车符):
# originaly spe1 but with grd ecl file meddled with for nesting
include tests
SIMULATION
SIMULATION_TYPE SUBSURFACE
PROCESS_MODELS
SUBSURFACE_FLOW Flow
MODE BLACK_OIL
OPTIONS
ANALYTICAL_JACOBIAN
ISOTHERMAL
/
/ ! end of subsurface_flow
/ ! end of process models
CHECKPOINT
/
END !! end simulation block
SUBSURFACE
external_file example1.dat
include example2.dat
匹配包含:
匹配 = [example1.dat,example2.dat]
但是对于像下面这样只包含关键字和其他文本的简单字符串,它是失败的:
external_file example3.dat
include example4.dat
返回一个空数组或仅返回最后一项(有点随机):
匹配 = [example4.dat] 或匹配 =[]
任何想法?谢谢你。
更新
OK,修改导入文本后:
external_file example3.dat
include example4.dat
database example5.dat
我意识到我的匹配数组只缺少第一项:
匹配 = [example4.dat,example5.dat]
如何修改正则表达式以包含 example3.dat?
解决方案
我会稍微不同地解决它。
import re
test1 = """include tests
SIMULATION
SIMULATION_TYPE SUBSURFACE
PROCESS_MODELS
SUBSURFACE_FLOW Flow
MODE BLACK_OIL
OPTIONS
ANALYTICAL_JACOBIAN
ISOTHERMAL
/
/ ! end of subsurface_flow
/ ! end of process models
CHECKPOINT
/A
END !! end simulation block
SUBSURFACE
external_file example1.dat
include example2.dat"""
test2 = """external_file example3.dat
include example4.dat"""
token = re.findall(r'\S+', test1)
token
>>>['include',
'tests',
'SIMULATION',
'SIMULATION_TYPE',
'SUBSURFACE',
'PROCESS_MODELS',
'SUBSURFACE_FLOW',
'Flow',
'MODE',
'BLACK_OIL',
'OPTIONS',
'ANALYTICAL_JACOBIAN',
'ISOTHERMAL',
'/',
'/',
'!',
'end',
'of',
'subsurface_flow',
'/',
'!',
'end',
'of',
'process',
'models',
'CHECKPOINT',
'/',
'END',
'!!',
'end',
'simulation',
'block',
'SUBSURFACE',
'external_file',
'example1.dat',
'include',
'example2.dat']
当你对你的词进行标记时,我会构建双元语法
bi_grams = [(a,b) for a,b in zip(token[:-1], token[1:]) ]
然后过滤那些包含您的文件令牌的双元词作为第一个条目
file_tokens = ('DATABASE', 'EXTERNAL_FILE', 'FILE', 'FILENAME', 'INCLUDE')
bi_grams_of_interest = [bi_gram for bi_gram in bi_grams if bi_gram[0].upper() in file_tokens]
bi_grams_of_interest
>>>[('include', 'tests'),
('external_file', 'example1.dat'),
('include', 'example2.dat')]
如果你为 test2 运行它,我会得到以下输出
>>>[('external_file', 'example3.dat'), ('include', 'example4.dat')]
推荐阅读
- python - 如何浏览查询结果并写入行(跳过重复)?
- sql - 从表中获取员工和经理的统计数据
- php - 如何从苗条的中间件中获取属性
- awk - 用 awk 替换 " by '
- sql-server - SQL Server - 大容量插入 - FIELDQUOTE 无法识别双引号
- python - 根据python中的条件检查执行路径
- node.js - 导出已解决的承诺结果
- prometheus - 普罗米修斯查询中来自grafana变量的多个值
- scala - 是否可以根据用于分区数据集的列的值动态命名部分 XXXX 文件?
- python - 如何在不同的文件中运行多个 Keras 神经网络模型?