の前にすべてをどのように取得しますか:文字列Python


102

:の前に文字列内のすべての文字を取得する方法を探していますが、どこから始めればよいかわかりません。正規表現を使用しますか?もしそうなら?

string = "Username: How are you today?"

誰かが私にできることの例を教えてくれますか?

回答:


169

split関数を使用するだけです。リストを返すので、最初の要素を保持できます。

>>> s1.split(':')
['Username', ' How are you today?']
>>> s1.split(':')[0]
'Username'

12
いずれかの制限分割、またはこの場合-使用s1.partition(':')[0]
ジョンクレメンツ

これは非常に有用で有益でしたありがとう。さらに、それは大きな助けのおかげです!
0Cool

1
すべての ':'を処理して完全な配列を作成するため、分割は使用しないでください。長い文字列には適していません。インデックスを使用するための@Hackaholicのアプローチを参照してください。それだけでは、明らかに効果的でない正規表現を推奨しています。また、インデックスベースの.substringBefore()の標準操作を実行するには、Pythonオプションが必要です。また、.substringBeforeLast()などのバリエーションも便利です(コードは繰り返さないでください)。パーティションに関する注意点-はい、「:」の後の処理は少なくなりますが、それでも「1」ではなく<class 'tuple'>:( '1'、 ':'、 '2:3')を返します。
1

43

使用index

>>> string = "Username: How are you today?"
>>> string[:string.index(":")]
'Username'

インデックスはあなたに位置を与えます :文字列内、それをスライスできます。

正規表現を使用する場合:

>>> import re
>>> re.match("(.*?):",string).group()
'Username'                       

match 文字列の先頭から一致します。

あなたも使うことができます itertools.takewhile

>>> import itertools
>>> "".join(itertools.takewhile(lambda x: x!=":", string))
'Username'

3
このメソッド(string [:string.index( ":")])は、おそらく分割よりもクリーンです
Damien

速度のために正規表現を使用しないでください-ここで述べた最初のインデックスオプションを使用してください。正規表現は明らかに効果的ではありません。また、インデックスベースの.substringBefore()の標準操作を実行するには、Pythonオプションが必要です。また、.substringBeforeLast()などのバリエーションも便利です(コードは繰り返さないでください)。この回答を更新して、インデックスがより効果的に機能する理由を説明し、次に、これがfredtantiniの応答でより高い投票数を含む他のアプローチよりも使用する必要がある理由を説明することを提案します。
1

存在しない場合、インデックスは失敗します。
マルク

18

regexこれは必要ありません

>>> s = "Username: How are you today?"

あなたは使用することができますsplit上の文字列を分割する方法を':'文字

>>> s.split(':')
['Username', ' How are you today?']

そして要素[0]をスライスして文字列の最初の部分を取得します

>>> s.split(':')[0]
'Username'

7

私はこれらのさまざまな技術をPython 3.7.0(IPython)でベンチマークしました。

TLDR

  • 最速(分割記号cがわかっている場合):コンパイル済みの正規表現。
  • (それ以外)最速:s.partition(c)[0]
  • 安全(つまり、にcない場合がありますs):パーティション、分割。
  • 安全でない:インデックス、正規表現。

コード

import string, random, re

SYMBOLS = string.ascii_uppercase + string.digits
SIZE = 100

def create_test_set(string_length):
    for _ in range(SIZE):
        random_string = ''.join(random.choices(SYMBOLS, k=string_length))
        yield (random.choice(random_string), random_string)

for string_length in (2**4, 2**8, 2**16, 2**32):
    print("\nString length:", string_length)
    print("  regex (compiled):", end=" ")
    test_set_for_regex = ((re.compile("(.*?)" + c).match, s) for (c, s) in test_set)
    %timeit [re_match(s).group() for (re_match, s) in test_set_for_regex]
    test_set = list(create_test_set(16))
    print("  partition:       ", end=" ")
    %timeit [s.partition(c)[0] for (c, s) in test_set]
    print("  index:           ", end=" ")
    %timeit [s[:s.index(c)] for (c, s) in test_set]
    print("  split (limited): ", end=" ")
    %timeit [s.split(c, 1)[0] for (c, s) in test_set]
    print("  split:           ", end=" ")
    %timeit [s.split(c)[0] for (c, s) in test_set]
    print("  regex:           ", end=" ")
    %timeit [re.match("(.*?)" + c, s).group() for (c, s) in test_set]

結果

String length: 16
  regex (compiled): 156 ns ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.3 µs ± 430 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            26.1 µs ± 341 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.3 µs ± 835 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 256
  regex (compiled): 167 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  index:            28.6 µs ± 2.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.4 µs ± 979 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            31.5 µs ± 4.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            148 µs ± 7.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

String length: 65536
  regex (compiled): 173 ns ± 3.95 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 613 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 515 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.2 µs ± 796 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.5 µs ± 377 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 4294967296
  regex (compiled): 165 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.9 µs ± 144 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 571 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.1 µs ± 472 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            28.1 µs ± 1.69 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            137 µs ± 6.53 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

インデックスを安全ではないと考えるのはなぜですか?
ジェームズ

2
s.index(c)cがにない場合、ValueErrorが発生しsます。したがって、パーティション化される文字列にセパレータが含まれていることが確実な場合は安全と見なし、それ以外の場合は安全ではないと見なします。
アリスティド

インデックスの場合、cはsに含まれるため、安全ではなく、最速です。
1

2

区切り文字がないか、区切り文字が多い状況では、partition()の方がsplit()よりもこの目的に適している可能性があります。


1
partitionsplitはどちらも、空の文字列または区切り文字なしで透過的に機能します。word[:word.index(':')]これらのケースの両方でポップが発生することは注目に値します。
ロブ・ホール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.