我尝试了许多模式,但无法得到正确的结果。当行的开头有关键字range
时,我只想匹配float。我的问题是range
后面可能跟着:
、:
、:
、:
、:
等
我最好的尝试是使用两种模式:
#1.(?i)(?<=range[: ])[:a-zA-Z0-9.$ -]+
#2.[0-9.]+
首先使用模式#1运行regex,然后获得模式#1的输出,并使用模式#2 再次运行regex
我如何在一个单一的模式中做到这一点?非常感谢
还有一件事:我的代码是Python
输入:range: $0.82
-->预期输出:0.82
输入:range:0.82
-->预期输出:0.82
输入:range: 0.82 - 0.85
-->预期输出:0.82
、0.85
输入:range : 0.82 - 0.85
-->预期输出:0.82
、0.85
输入:range : 0.82 - 0.85
-->预期输出:0.82
、0.85
输入:range 0.82 0.85
-->预期输出:0.82
、0.85
如果您可以使用Pythonregex-PyPi模块,那么您可以获得多次出现:
(?<=^rangeb[s:$-d.]*)d+(?:.d+)?
解释
(?<=
正向向后看,断言左边是^rangeb
在字符串开头匹配range
[s:$-d.]*
(可选(匹配可能介于
)
关闭后备断言d+(?:.d+)?
将1+位数字与可选小数部分匹配
Regex演示| Python演示
示例
import regex
strings = [
"range: $0.82",
"range:0.82",
"range: 0.82 - 0.85",
"range : 0.82 - 0.85",
"range : 0.82 - 0.85",
"range 0.82 0.85"
]
pattern = r"(?<=^rangeb[s:$-d.]*)d+(?:.d+)?"
for s in strings:
print (regex.findall(pattern, s))
输出
['0.82']
['0.82']
['0.82', '0.85']
['0.82', '0.85']
['0.82', '0.85']
['0.82', '0.85']
您可以完全避免regex。这些行不难解析。
def parse(line):
if not line.startswith('range'):
return
line = line.replace(':',' ').replace('$','')
for token in line.split():
try:
yield float(token)
except ValueError:
continue
input_data = ['range: $0.82',
'range:0.82',
'range: 0.82 - 0.85',
'range : 0.82 - 0.85',
'range : 0.82 - 0.85',
'range 0.82 0.85']
r = [list(i) for i in map(parse, input_data)]
print(r)
[[0.82], [0.82], [0.82, 0.85], [0.82, 0.85], [0.82, 0.85], [0.82, 0.85]]
这似乎对我有效-然而,可能有许多更有效的方法:
import re
input_data = ['range: $0.82',
'range:0.82',
'range: 0.82 - 0.85',
'range : 0.82 - 0.85',
'range : 0.82 - 0.85',
'range 0.82 0.85']
for i in range(len(input_data)):
output = re.findall(r'(range)(s*:?s*[$]*)([0-9]*.[0-9]*)(s*-?s*)([0-9]*.[0-9]*)?', input_data[i])
a = list(output[0])[2]
b = list(output[0])[4]
print(f'Input: {input_data[i]} --> Expected output: {a} , {b}')
输出:
Input: range: $0.82 --> Expected output: 0.82 ,
Input: range:0.82 --> Expected output: 0.82 ,
Input: range: 0.82 - 0.85 --> Expected output: 0.82 , 0.85
Input: range : 0.82 - 0.85 --> Expected output: 0.82 , 0.85
Input: range : 0.82 - 0.85 --> Expected output: 0.82 , 0.85
Input: range 0.82 0.85 --> Expected output: 0.82 , 0.85
您还可以添加一些IF语句来检查"b"是否为空,并根据需要控制输出。然而,我认为您想要实现的主要内容是一个单独的REGEX语句,它可以提取有问题的两个数字(如果可用(。
Regex语句解释:
r'(range)(s*:?s*[$]*)([0-9]*.[0-9]*)(s*-?s*)([0-9]*.[0-9]*)?'
第一组:(range)
这将">范围"放入第一组。
第二组:(s*:?s*[$]*)
s*
匹配零个或多个空白字符:?
匹配可选冒号(:([$]*
匹配零个或多个美元符号($(
第三组:([0-9]*.[0-9]*)
[0-9]*
匹配零个或多个数字.
匹配小数点- 这是与数字相关的组(0.82(
第四组:(s*-?s*)
s*
匹配零个或多个空白字符-?
匹配可选连字符
第五组:([0-9]*.[0-9]*)?
[0-9]*
匹配零个或多个数字.
匹配小数点- 最后的
?
表明该组是可选的 - 这是持有第二个数字的组(0.85(
您可以使用此正则表达式提取数据:
^s*rangeD*(d+(?:.d+)?)(?:D*(d+(?:.d+)?))?
Regex解释:
^
:字符串的开头s*range
:断言字符串以range
开头(如果您不想删除s*
,可能前面有空格D*
:一定数量的非数字字符(d+(?:.d+)?)
:一个数字,在第1组中捕获(?:D*(d+(?:.d+)?))?
一组可选的非数字,后面跟着一个数字,在第2组中捕获
在python 中
import re
input_data = ['range: $0.82',
'range:0.82',
'range: 0.82 - 0.85',
'range : 0.82 - 0.85',
'range : 0.82 - 0.85',
'range 0.82 0.85']
results = [re.findall(r'^s*rangeD*(d+(?:.d+)?)(?:D*(d+(?:.d+)?))?', d)[0] for d in input_data]
print(results)
输出:
[
('0.82', ''),
('0.82', ''),
('0.82', '0.85'),
('0.82', '0.85'),
('0.82', '0.85'),
('0.82', '0.85')
]