我的任务是从文本文件或字符串中删除所有非数字字符,包括空格,然后在旧字符旁边打印新结果,例如:
前:
sd67637 8
后:
676378
由于我是初学者,我不知道从哪里开始这项任务。请帮忙
我的任务是从文本文件或字符串中删除所有非数字字符,包括空格,然后在旧字符旁边打印新结果,例如:
前:
sd67637 8
后:
676378
由于我是初学者,我不知道从哪里开始这项任务。请帮忙
最简单的方法是使用正则表达式
import re
a = 'lkdfhisoe78347834 (())&/&745 '
result = re.sub('[^0-9]','', a)
print result
>>> '78347834745'
逐个字符地循环遍历您的字符串,并且仅包含数字:
new_string = ''.join(ch for ch in your_string if ch.isdigit())
或者在您的字符串上使用正则表达式(如果在某些时候您想分别处理非连续组)...
import re
s = 'sd67637 8'
new_string = ''.join(re.findall(r'\d+', s))
# 676378
然后print
把它们拿出来:
print(old_string, '=', new_string)
有一个内置的。
string.translate(s, table[, deletechars])
从 s 中删除 deletechars(如果存在)中的所有字符,然后使用 table 翻译字符,table 必须是一个 256 个字符的字符串,给出每个字符值的翻译,按其序数索引。如果 table 为 None,则仅执行字符删除步骤。
>>> import string
>>> non_numeric_chars = ''.join(set(string.printable) - set(string.digits))
>>> non_numeric_chars = string.printable[10:] # more effective method. (choose one)
'sd67637 8'.translate(None, non_numeric_chars)
'676378'
或者你可以在没有进口的情况下做到这一点(但没有理由这样做):
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> 'sd67637 8'.translate(None, chars)
'676378'
您可以使用string.ascii_letters
来识别您的非数字:
from string import *
a = 'sd67637 8'
a = a.replace(' ', '')
for i in ascii_letters:
a = a.replace(i, '')
如果您想替换冒号,请使用引号"
而不是冒号'
。
我不会为此使用 RegEx。它慢了很多!
相反,让我们使用一个简单的for
循环。
此功能将快速完成工作...
def filter_non_digits(string: str) -> str:
result = ''
for char in string:
if char in '1234567890':
result += char
return result
让我们创建一个非常基本的基准来测试已经提出的几种不同方法。我将测试三种方法...
# filters.py
import re
# For loop method
def filter_non_digits_for(string: str) -> str:
result = ''
for char in string:
if char in '1234567890':
result += char
return result
# Comprehension method
def filter_non_digits_comp(s: str) -> str:
return ''.join(ch for ch in s if ch.isdigit())
# RegEx method
def filter_non_digits_re(string: str) -> str:
return re.sub('[^\d]','', string)
现在我们已经实现了每种删除数字的方法,让我们对每一种方法进行基准测试。
这是一些非常基本和基本的基准代码。但是,它可以解决问题,并让我们很好地比较每种方法的执行方式。
# tests.py
import time, platform
from filters import filter_non_digits_re,
filter_non_digits_comp,
filter_non_digits_for
def benchmark_func(func):
start = time.time()
# the "_" in the number just makes it more readable
for i in range(100_000):
func('afes098u98sfe')
end = time.time()
return (end-start)/100_000
def bench_all():
print(f'# System ({platform.system()} {platform.machine()})')
print(f'# Python {platform.python_version()}\n')
tests = [
filter_non_digits_re,
filter_non_digits_comp,
filter_non_digits_for,
]
for t in tests:
duration = benchmark_func(t)
ns = round(duration * 1_000_000_000)
print(f'{t.__name__.ljust(30)} {str(ns).rjust(6)} ns/op')
if __name__ == "__main__":
bench_all()
这是基准代码的输出。
# System (Windows AMD64)
# Python 3.9.8
filter_non_digits_re 2920 ns/op
filter_non_digits_comp 1280 ns/op
filter_non_digits_for 660 ns/op
如您所见,该filter_non_digits_for()
函数比使用 RegEx 快四倍以上,大约是理解方法的两倍。有时简单是最好的。
示例:sd67637 8 ==> 676378
import re
def extract_int(x):
return re.sub('[^\d]','', x)
示例:sd7512.sd23 ==> 7512.23
import re
def extract_single_float(x):
return re.sub('[^\d|\.]','', x)
示例:123.2 xs12.28 4 ==> [123.2, 12.28, 4]
import re
def extract_floats(x):
return re.findall("\d+\.\d+", x)
添加到 @MoradneJad 中。您可以使用以下代码提取整数值、浮点数甚至有符号值。
a = re.findall(r"[-+]?\d*\.\d+|\d+", "Over th44e same pe14.1riod of time, p-0.8rices also rose by 82.8p")
然后您可以使用有效地将列表项转换为数字数据类型map
。
print(list(map(float, a)))
[44.0, 14.1, -0.8, 82.8]