您的问题实际上是多个问题。从“数据框”标签来看,您似乎正在使用 pandas 执行此操作。您询问的正则表达式可能会增加 'yl' 和 'rd' 的数字(如果有的话,我假设它们总是在那里)。但是正则表达式通常不进行数学或数值比较,所以这是第三位。
匹配 'yl' 数值的正则表达式(假设整数,而不是浮点数):
r'yl@(\d+)'
您可以在单个表达式中提取它们,但这会假定它们始终处于相同的顺序,或者变成一个复杂的正则表达式。
为了确保只有yl@5 匹配,而xyl@5 不匹配,您可以在开头(需要空格或行首)和结尾(需要空格或行尾)添加一些限制:
r'(^|\s)yl@(\d+)($|\s)'
或者,如果您遇到yl 是名称空间的情况,例如a:yl,您也可以添加它:
r'(^|\s)([a-z]+:)?l@(\d+)($|\s)'
然而,所有这些只是使用正则表达式语言构建更具体的表达式。我喜欢使用的一个非常好的编写正则表达式的工具(没有隶属关系)是 RegexBuddy,但也有非常好的在线工具,比如https://regex101.com/。
在代码示例中使用基本上按照您的建议进行:
import re
from pandas import DataFrame
df = DataFrame({
'Format': ['A', 'B', 'C'],
'Message': ['ab@1 yl@5 rd@20 pp@40', 'bc@1 gn@7 yl@20 ss@25 rd@50', 'cc@1 yl@9 rd@20'],
'time': [3, 21, 22]
})
def determine_status(row):
def find(tag, message):
match = re.search(rf"{tag}@(\d+)", message)
if match:
return match.group(1)
else:
raise ValueError(f'{tag} not in message.')
yl = int(find('yl', row['Message']))
rd = int(find('rd', row['Message']))
time = int(row['time'])
if time < yl < rd:
return 'g'
if yl <= time < rd:
return 'y'
return 'r'
df['status'] = df.apply(determine_status, axis=1)
print(df)
find 函数接受标签和消息,并使用正则表达式为消息中的标签生成数值。
determine_status 函数就是这样做的 - 它需要来自 DataFrame 的一行,并将使用 Message 和 time 列来确定状态并返回它。
df.apply 然后用于创建一个新的status 列,并为DataFrame 中的每一行填充determine_status 的结果。
您没有指定您使用的 Python 版本,但如果它是 Python 3.6 之前的版本,您会发现像 f'{tag} not in message.' 这样的表达式将不起作用 - 相反,您会使用像 @987654338 这样的表达式@。