我有一个程序,其输入已更改。它最初使用整数时有效,并且整数的单位如下:“ kbps”,“ Mbps”,“ Gbps”。一个例子:
10kbps
20Mbps
20Gbps
我使用“ if / then”将所有字符串转换为bps:
if "kbps" in bandwidth:
bw=bandwidth.replace('kbps', '000')
elif "Mbps" in bandwidth:
bw=bandwidth.replace('Mbps', '000000')
elif "Gbps" in bandwidth:
bw=bandwidth.replace('Gbps', '000000000')
else:
bw='0'
我将“ bw”打印为整数“ int(bw)”,并且工作正常。现在,输入已更改。这是实际输入的示例:
3.838Mbps
100kbps
126.533kbps
5.23Mbps
100Mbps
1.7065Gbps
20Gbps
数字不是整数。因为它不是整数,所以我不仅不能打印,而且单位转换不能与小数一起使用。例如,3.838Mbps变为3.838000000。
有人可以建议使用这些输入的有效方法吗?我找不到分割,正则表达式匹配等的正确平衡,并且想知道是否有一些我不知道的方法。
答案 0 :(得分:4)
我会做类似的事情:
import re
UNITS = {
'k': 1e3,
'm': 1e6,
'g': 1e9,
't': 1e12,
}
def parse_bps(s):
m = re.match(r'^([0-9]+(\.[0-9]*)?)([tgmk])?bps$', s, re.IGNORECASE)
if not m:
raise ValueError(f"unsupported value for parse_bps: {repr(s)}")
val = float(m.group(1))
unit = m.group(3)
if unit:
val *= UNITS[unit.lower()]
return val
tests = [
'10bps', '10kbps', '20Mbps', '20Gbps', '3.838Mbps',
'3.838Mbps', '100kbps', '126.533kbps', '5.23Mbps',
'100Mbps', '1.7065Gbps', '20Gbps',
]
for s in tests:
print(f' {repr(s)} = {parse_bps(s)}')
尽管最好不要忽略大小写。 SI units正式根据大小写产生很大的差异,通常来说,大写字母表示乘法,小写字母表示除法。
答案 1 :(得分:4)
我认为在这里使用正则表达式并捕获“数字部分”和“单元前缀部分”可能会更好:
import re
bandwidth_rgx = re.compile(r'^(\d*(?:\.\d*)?)\s*([GMk]?)(?:bps)?$')
所以现在我们可以匹配给定的字符串,并获得数字部分和单位前缀部分:
>>> bandwidth_rgx.search('126.533kbps')[1]
'126.533'
>>> bandwidth_rgx.search('126.533kbps')[2]
'k'
所以我们可以制作一个转换字典,例如:
unit_prefix = {
'': 1,
'k': 1000,
'M': 1000000,
'G': 1000000000
}
并使用一个函数来获取带宽,例如作为浮点数:
def get_bandwidth(text):
m = bandwidth_rgx.search(text)
return float(m[1]) * unit_prefix[m[2]]
例如:
>>> get_bandwidth('3.838Mbps')
3838000.0
>>> get_bandwidth('100kbps')
100000.0
>>> get_bandwidth('126.533kbps')
126533.0
>>> get_bandwidth('5.23Mbps')
5230000.0
>>> get_bandwidth('100Mbps')
100000000.0
>>> get_bandwidth('1.7065Gbps')
1706500000.0
>>> get_bandwidth('20Gbps')
20000000000.0
答案 2 :(得分:4)
您可以在kbps
,Mbps
或Gbps
之前强制转换值以进行浮动,然后乘以1000、1000,000等。无论哪种情况都可以。
例如:
if "kbps" in bandwidth:
bw = bandwidth.replace('kbps', '')
bw = str(float(bw) * 1000)
elif "Mbps" in bandwidth:
bw = bandwidth.replace('Mbps', '')
bw = str(float(bw) * 1000* 1000)
elif "Gbps" in bandwidth:
bw = bandwidth.replace('Gbps', '')
bw = str(float(bw) * 1000 * 1000 * 1000)
else:
bw='0'
答案 3 :(得分:1)
需要最少的代码更改并假设您的输入是安全的答案:
if "kbps" in bandwidth:
bw=bandwidth.replace('kbps', '* 1e3')
elif "Mbps" in bandwidth:
bw=bandwidth.replace('Mbps', '* 1e6')
elif "Gbps" in bandwidth:
bw=bandwidth.replace('Gbps', '* 1e9')
else:
bw='0'
bw_int = eval(bandwidth)
当然,请确保您的输入是安全的,并且eval
(Why is using 'eval' a bad practice?)有一些安全性和性能方面的考虑,但是有时,您只是想快速了解一下:)>