我有这个正则表达式:
cont_we_re = r"((?!\S+\s?(?:(cbf|cd3|cbm|m3|m[\\\>\?et]?|f3|ft3)))(?:([0-9,\.]+){2,})(?:\s*(?:(lb|kg)\.?s?))?)"
现在,如果后跟 kgs 或 lbs,则后面的逻辑可选地与任何数字 block 匹配,但如果 cbf,则不匹配>, cd3, cbm, m3 等在数字 block 之后。它非常适合这些示例案例:
s1 = "18300 kg 40344.6 lbs 25000 m3"
s2 = "18300kg 40344.6lbs 25000m3"
s3 = "18300 kg KO"
s4 = "40344.6 lb5 "
s5 = "40344.6 "
我正在使用带有 re.IGNORECASE 标志的 re.finditer(),像这样:
for s in [s1, s2, s3, s4, s5]:
all_val = [i.group().strip() for i in re.finditer(cont_we_re, s, re.IGNORECASE)]
给我这个输出:
['18300 kg', '40344.6 lbs']
['18300kg', '40344.6lbs']
['18300 kg']
['40344.6 lb']
['40344.6']
现在我正在尝试实现另一个逻辑:如果我们找到后跟 lbs 的数字 block ,则将其与第一优先级匹配并仅返回该匹配项,但如果找不到 lbs 并只找到数字 block 或数字 block 后跟 kgs 然后取那些。
我在不更改正则表达式的情况下完成了此操作,如下所示:
for s in [s1, s2, s3, s4, s5]:
all_val = [i.group().strip() for i in re.finditer(cont_we_re, s, re.IGNORECASE)]
kg_val = [i for i in all_val if re.findall(r"kg\.?s?", i)]
lb_val = [i for i in all_val if re.findall(r"lb\.?s?", i)]
final_val = lb_val if lb_val else (kg_val if kg_val else list(set(all_val) - (set(kg_val+lb_val))))
这给了我想要的输出(这是完美的):
['40344.6 lbs']
['40344.6lbs']
['18300 kg']
['40344.6 lb']
['40344.6']
问题是我如何在正则表达式中应用相同的逻辑,而不通过 cont_we_re 在每个匹配组上分别找到 kgs 和 lbs对于每个字符串。我尝试了此 question 中描述的“IF-THEN-ELSE”类型正则表达式但它不能作为正则表达式的第一部分 (? 据说会在 python 中产生模式错误。有没有办法只用 cont_we_re 正则表达式来做到这一点?
请您参考如下方法:
使用 PyPi module 的可能解决方案可能正在利用 (*SKIP)(*FAIL)和环顾四周以检查是否存在 lb
(?:\d+(?:\.\d+)? ?lbs?|(?<!lb.*)(?!.*lb)\d+(?:\.\d+)?(?: kg)?|\d+(?:\.\d+)? ?kg(*SKIP)(*FAIL))
-
(?:非捕获组-
\d+(?:\.\d+)? ?lbs?将数字格式与可选的小数部分匹配,后跟 lb 和可选的 s -
|或者 -
(?<!lb.*)(?!.*lb)\d+(?:\.\d+)?(?: kg)?断言字符串不包含lb, 然后将数字格式与可选的小数部分匹配,后跟kg -
|或者 -
\d+(?:\.\d+)? ?kg(*SKIP)(*FAIL)匹配数字格式后接kg并跳过那场比赛
-
-
)关闭非捕获组
例如
import regex
s1 = "18300 kg 40344.6 lbs 25000 m3"
s2 = "18300kg 40344.6lbs 25000m3"
s3 = "18300 kg KO"
s4 = "40344.6 lb5 "
s5 = "40344.6 "
cont_we_re = r"(?:\d+(?:\.\d+)? ?lbs?|(?<!lb.*)(?!.*lb)\d+(?:\.\d+)?(?: kg)?|\d+(?:\.\d+)? ?kg(*SKIP)(*FAIL))"
for s in [s1, s2, s3, s4, s5]:
all_val = [i.group().strip() for i in regex.finditer(cont_we_re, s, regex.IGNORECASE)]
print(all_val)
输出
['40344.6 lbs']
['40344.6lbs']
['18300 kg']
['40344.6 lb']
['40344.6']
