58

テキストファイルまたは文字列からスペースを含むすべての非数値文字を削除し、新しい結果を古い文字の横に出力するタスクが与えられました。たとえば、次のようになります。

前:

sd67637 8

後:

676378

私は初心者なので、このタスクをどこから始めればよいかわかりません。助けてください

4

7 に答える 7

101

最も簡単な方法は、正規表現を使用することです

import re
a = 'lkdfhisoe78347834 (())&/&745  '
result = re.sub('[^0-9]','', a)

print result
>>> '78347834745'
于 2013-06-27T07:52:27.650 に答える
27

文字列を 1 文字ずつループし、数字のみを含めます。

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)
于 2013-06-27T07:20:54.147 に答える
10

これにはビルトインがあります。

string.translate(s, table[, deletechars])

deletechars (存在する場合) にある s からすべての文字を削除し、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'
于 2013-06-27T07:36:31.130 に答える
1

これには正規表現を使用しません。それはずっと遅いです!

for代わりに、単純なループを使用しましょう。

TLDR;

この機能により、仕事が速く完了します...

def filter_non_digits(string: str) -> str:
    result = ''
    for char in string:
        if char in '1234567890':
            result += char
    return result 

説明

提案されているいくつかの異なる方法をテストするための非常に基本的なベンチマークを作成しましょう。3つの方法をテストします...

  1. forループ方式(私の考え)。
  2. Jon Clements' answerからの理解方法をリストします。
  3. Moradnejad 's answerからの RegEx メソッド。
# 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 を使用するよりも 4 倍以上高速であり、理解メソッドよりも約 2 倍高速です。時にはシンプルイズベスト。

于 2021-11-29T22:01:17.360 に答える
0

@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]

于 2021-10-16T17:55:28.240 に答える