2 回答
TA贡献1796条经验 获得超7个赞
您可以使用可选的第三组而不使用交替|
并检查它是否存在
^[^\S\r\n]*(\S+)[^\d\r\n]+(\d+(?:\.\d+)?)[^\d\r\n]*(\d+(?:\.\d+)?)?
在部分
^
字符串的开始[^\S\r\n]*
匹配 0+ 次除换行符外的空白字符(\S+)
捕获组 1,匹配 1+ 个非空白字符[^\d\r\n]+
匹配除换行符或数字以外的任何字符 1 次以上(\d+(?:\.\d+)?)
捕获第 2 组,匹配带有可选小数部分的数字[^\d\r\n]*
匹配 + 乘以除换行符或数字以外的任何字符(\d+(?:\.\d+)?)?
可选的捕获组 3,匹配带有可选小数部分的数字
例如
import re
regex = r"^[^\S\r\n]*(\S+)[^\d\r\n]+(\d+(?:\.\d+)?)[^\d\r\n]*(\d+(?:\.\d+)?)?"
dict = {}
test_str = (" hUbo2 21.8. ssol/t vsdw \n"
" AE(k) =3.0 asdsddf/as\n"
" Cat+ 1.1 fasdl/ aoKw \n"
"Glu 38\n"
"Dac < 0.30\n"
" DH 7.350 - 7.450\n"
" iKo2 35.0 —- 48.0\n"
" LE(dcf) 2.0- 3.0\n"
" Lp+ 138 ~ 146\n"
" C1- 98 - 107 hjkkl/asL \n"
" LKu 74 ~ 100 \n"
" Arsa 9.51 - 1.19 \n"
" s$92 94.0 - 98.0 % ")
matches = re.finditer(regex, test_str, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
dict[match.group(1)] = match.group(2) + ( " " + match.group(3) if match.group(3) else "")
print(dict)
输出
{'hUbo2': '21.8', 'AE(k)': '3.0', 'Cat+': '1.1', 'Glu': '38', 'Dac': '0.30', 'DH': '7.350 7.450', 'iKo2': '35.0 48.0', 'LE(dcf)': '2.0 3.0', 'Lp+': '138 146', 'C1-': '98 107', 'LKu': '74 100', 'Arsa': '9.51 1.19', 's$92': '94.0 98.0'}
使用提供的代码的示例:
import re
pattern = r"^[^\S\r\n]*(\S+)[^\d\r\n]+(\d+(?:\.\d+)?)[^\d\r\n]*(\d+(?:\.\d+)?)?"
dict = {}
for i, line in enumerate(open(mytext_file)):
for match in re.finditer(pattern, line):
try:
abcd = float(match.group(2).strip())
dict[match.group(1)] = '{}{}'.format(abcd, (" " + match.group(3) if match.group(3) else ""))
except Exception:
pass
print(dict)
TA贡献1795条经验 获得超7个赞
这是一个小的 python 脚本(包括正则表达式),当您通过 stdin 传输数据时,它会转换您的数据:
import fileinput
import re
for line in fileinput.input():
line = re.sub(r'^\s*(\S+)\D+([\d.]*\d)\D*((?:[\d.]*\d)?)\D*$', r'\1 \2 \3', line.rstrip())
print(line)
以下是您将如何使用它及其输出:
cat data.txt | python regex.py
hUbo2 21.8
AE(k) 3.0
Cat+ 1.1
Glu 38
Dac 0.30
DH 7.350 7.450
iKo2 35.0 48.0
LE(dcf) 2.0 3.0
Lp+ 138 146
C1- 98 107
LKu 74 100
Arsa 9.51 1.19
s$92 94.0 98.0
(如果您使用的是 Windows,请使用type而不是cat 。)
添加回答
举报