Pythonで文字列の末尾から部分文字列を削除するにはどうすればよいですか?


382

私は次のコードを持っています:

url = 'abcdc.com'
print(url.strip('.com'))

私は期待しました: abcdc

私は得ました: abcd

今私がやります

url.rsplit('.com', 1)

もっと良い方法はありますか?


6
stripは、文字列の両端から与えられた文字を取り除きます。あなたの場合、「。」、「c」、「o」、「m」を取り除きます。
truppo 09年

6
また、文字列の先頭からこれらの文字を削除します。最後から削除したい場合は、rstrip()を使用します
Andre Miller

42
うん。str.stripは、あなたが思っていることを実行しません。str.stripは、文字列の最初と最後から指定された文字を削除します。したがって、 "acbacda" .strip( "ad")は 'cbac'を返します。最初のaと最後のdaは取り除かれました。乾杯。
scvalex 09年

2
さらに、これは任意の順序で文字を削除します: "site.ocm"> "site"。
エリックOレビゴット2013

1
@scvalex、すごい、これは長い間このように使用していたことに気づきました
Flash

回答:


556

strip「この部分文字列を削除する」という意味ではありません。x.strip(y)y文字のセットとして扱い、そのセット内のすべての文字をの末尾から取り除きxます。

代わりに、使用endswithしてスライスすることができます:

url = 'abcdc.com'
if url.endswith('.com'):
    url = url[:-4]

または正規表現を使用する

import re
url = 'abcdc.com'
url = re.sub('\.com$', '', url)

4
ええ、私自身、endswith()テストを使用した最初の例の方が良いと思います。正規表現は、パフォーマンスのペナルティ(正規表現の解析など)を伴います。私はrsplit()を使用しませんが、それはあなたが正確に達成しようとしていることがわからないためです。.comがURLの最後に表示される場合にのみ削除されると思いますか?あなたは「www.commercialthingie.co.uk」のようなドメイン名でそれを使用したい場合はrsplitソリューションは、あなたの悩みを与えるだろう
Steef

13
url = url[:-4] if any(url.endswith(x) for x in ('.com','.net')) else url
Burhan Khalid 2013年

1
EXAMLPLE.COMドメイン名を書いた場合、大文字と小文字が区別されません。(これは正規表現ソリューションへの投票です)
Jasen

3
これは書き直しではありrsplit()ません。endswith()元の文字列の最後に部分文字列がなく、途中の部分にある場合の解決策と同じ動作はありません。例:"www.comeandsee.com".rsplit(".com",1)[0] == "www.comeandsee"but"www.comeandsee.net".rsplit(".com",1)[0] == "www"
Steef

1
構文s[:-n]には注意があります。の場合n = 0、これは最後のゼロ文字が切り取られた文字列を返さず、空の文字列を返します。
BlenderBender 2018年

90

文字列が最後にのみ表示されることが確かな場合は、 'replace'を使用するのが最も簡単な方法です。

url = 'abcdc.com'
print(url.replace('.com',''))

56
これものようなURLを置き換えwww.computerhope.comます。でチェックを行いendswith()、問題ないはずです。
ghostdog74

72
"www.computerhope.com".endswith(".com")本当です、それでも壊れます!

1
「文字列が最後にのみ表示されることが確かな場合」は、「部分文字列が1回だけ表示されることが確かな場合」を意味しますか?replaceは部分文字列が中央にある場合にも機能するようですが、他のコメントが示すように、部分文字列の発生を置き換えます。なぜそれが最後にあるのか理解できないのです
idclev 463035818

49
def strip_end(text, suffix):
    if not text.endswith(suffix):
        return text
    return text[:len(text)-len(suffix)]

4
サフィックスが空ではないことがわかっている場合(定数である場合など)、次のテキストを返します:text [:
-len

4
ありがとう。最終行は短縮される可能性があります:return text[:-len(suffix)]
Jabba 2013

3
@Jabba:残念ながら、fuenfundachtzigが述べたように、空のサフィックスでは機能しません。
yairchu 2013

46

まだ誰もこれを指摘していないようですので:

url = "www.example.com"
new_url = url[:url.rfind(".")]

これはsplit()、新しいリストオブジェクトが作成されないため、を使用するメソッドよりも効率的であり、このソリューションは複数のドットを持つ文字列に対して機能します。


すごいトリックです。私はこれを失敗させることはできませんでしたが、これが失敗するかもしれない方法を考えることができずに苦労しました。私はそれが好きですが、それを見るだけではこれが何をするのかを知るのは非常に「魔法」です。「手に入れる」ためには、線の各部分を精神的に処理しなければなりませんでした。
DevPlayer 2015

14
検索文字列が存在しない場合、これは失敗し、代わりに最後の文字が誤って削除されます。
robbat2

25

あなたがあなたのURLについて知っていること、そしてあなたが何をしようとしているのかによります。常に「.com」(または「.net」または「.org」)で終わることがわかっている場合は、

 url=url[:-4]

最速のソリューションです。それがより一般的なURLである場合は、おそらくpythonに付属しているurlparseライブラリを調べる方が良いでしょう。

一方、最後の「。」の後のすべてを単に削除したい場合。文字列で

url.rsplit('.',1)[0]

働くでしょう。または、最初の「。」までのすべてが必要な場合。してみてください

url.split('.',1)[0]

16

拡張機能であることがわかっている場合は、

url = 'abcdc.com'
...
url.rsplit('.', 1)[0]  # split at '.', starting from the right, maximum 1 split

これはabcdc.comor www.abcdc.comまたはor abcdc.[anything]と同じように機能し、より拡張可能です。




7

URLの場合(指定された例ではトピックの一部であると思われるため)、次のようなことができます。

import os
url = 'http://www.stackoverflow.com'
name,ext = os.path.splitext(url)
print (name, ext)

#Or:
ext = '.'+url.split('.')[-1]
name = url[:-len(ext)]
print (name, ext)

どちらも出力されます: ('http://www.stackoverflow', '.com')

これはstr.endswith(suffix)、「。com」などの特定のものだけを分割する必要がある場合にも組み合わせられます。


5

url.rsplit( '。com'、1)

正しくありません。

あなたが実際に書く必要があるのは

url.rsplit('.com', 1)[0]

、そしてそれはかなり簡潔な私見です。

ただし、使用するパラメーターは1つだけなので、私の個人的な好みはこのオプションです。

url.rpartition('.com')[0]

1
+1パーティションは、常に回答を返すため、1つの分割のみが必要な場合に推奨されます。IndexErrorは発生しません。
Gringo Suave 2018年


2

文字列が存在する場合、その一部を取り除く必要がある場合は、何もしません。私の最高のソリューション。おそらく最初の2つの実装のいずれかを使用することになりますが、完全を期すために3番目を実装しました。

定数サフィックスの場合:

def remove_suffix(v, s):
    return v[:-len(s) if v.endswith(s) else v
remove_suffix("abc.com", ".com") == 'abc'
remove_suffix("abc", ".com") == 'abc'

正規表現の場合:

def remove_suffix_compile(suffix_pattern):
    r = re.compile(f"(.*?)({suffix_pattern})?$")
    return lambda v: r.match(v)[1]
remove_domain = remove_suffix_compile(r"\.[a-zA-Z0-9]{3,}")
remove_domain("abc.com") == "abc"
remove_domain("sub.abc.net") == "sub.abc"
remove_domain("abc.") == "abc."
remove_domain("abc") == "abc"

定数サフィックスのコレクションの場合、多数の呼び出しに対して漸近的に最速の方法:

def remove_suffix_preprocess(*suffixes):
    suffixes = set(suffixes)
    try:
        suffixes.remove('')
    except KeyError:
        pass

    def helper(suffixes, pos):
        if len(suffixes) == 1:
            suf = suffixes[0]
            l = -len(suf)
            ls = slice(0, l)
            return lambda v: v[ls] if v.endswith(suf) else v
        si = iter(suffixes)
        ml = len(next(si))
        exact = False
        for suf in si:
            l = len(suf)
            if -l == pos:
                exact = True
            else:
                ml = min(len(suf), ml)
        ml = -ml
        suffix_dict = {}
        for suf in suffixes:
            sub = suf[ml:pos]
            if sub in suffix_dict:
                suffix_dict[sub].append(suf)
            else:
                suffix_dict[sub] = [suf]
        if exact:
            del suffix_dict['']
            for key in suffix_dict:
                suffix_dict[key] = helper([s[:pos] for s in suffix_dict[key]], None)
            return lambda v: suffix_dict.get(v[ml:pos], lambda v: v)(v[:pos])
        else:
            for key in suffix_dict:
                suffix_dict[key] = helper(suffix_dict[key], ml)
            return lambda v: suffix_dict.get(v[ml:pos], lambda v: v)(v)
    return helper(tuple(suffixes), None)
domain_remove = remove_suffix_preprocess(".com", ".net", ".edu", ".uk", '.tv', '.co.uk', '.org.uk')

最後のものはおそらくpypyよりもcpythonの方がはるかに高速です。正規表現のバリアントは、少なくともcPythonでは正規表現として簡単に表現できない潜在的なサフィックスの巨大な辞書を含まない事実上すべてのケースで、これよりも高速である可能性があります。

PyPyでは、reモジュールがDFAコンパイル正規表現エンジンを使用していても、ラムダのオーバーヘッドの大部分がJITによって最適化されるため、多数の呼び出しや長い文字列の正規表現バリアントはほぼ確実に遅くなります。

ただし、cPythonでは、正規表現用の実行中のcコードがほぼ確実に、ほとんどすべての場合にサフィックスコレクションバージョンのアルゴリズム上の利点を比較しています。


2

拡張機能のみを削除する場合:

'.'.join('abcdc.com'.split('.')[:-1])
# 'abcdc'

これは、任意の拡張子で機能し、他のドットもファイル名に存在する可能性があります。文字列をドットのリストとして分割し、最後の要素なしで結合します。


2
import re

def rm_suffix(url = 'abcdc.com', suffix='\.com'):
    return(re.sub(suffix+'$', '', url))

私はそれを行うための最も表現力豊かな方法としてこの答えを繰り返したいと思います。もちろん、以下の方がCPU時間は短くなります。

def rm_dotcom(url = 'abcdc.com'):
    return(url[:-4] if url.endswith('.com') else url)

しかし、CPUがボトルネックである場合、なぜPythonで記述するのですか?

とにかくCPUがボトルネックになるのはいつですか?ドライバーでは、多分。

正規表現を使用する利点は、コードの再利用性です。次に、3文字しか含まれていない「.me」を削除する場合はどうでしょうか。

同じコードでうまくいきます:

>>> rm_sub('abcdc.me','.me')
'abcdc'

1

私の場合、私は例外を発生させる必要があったので、私はしました:

class UnableToStripEnd(Exception):
    """A Exception type to indicate that the suffix cannot be removed from the text."""

    @staticmethod
    def get_exception(text, suffix):
        return UnableToStripEnd("Could not find suffix ({0}) on text: {1}."
                                .format(suffix, text))


def strip_end(text, suffix):
    """Removes the end of a string. Otherwise fails."""
    if not text.endswith(suffix):
        raise UnableToStripEnd.get_exception(text, suffix)
    return text[:len(text)-len(suffix)]


1

ドメインが何であっても(.com、.netなど)ドメインを削除したいとします。を見つけて.、その時点からすべてを削除することをお勧めします。

url = 'abcdc.com'
dot_index = url.rfind('.')
url = url[:dot_index]

ここで私は名前のように削減されるべきであるrfindようなURLの問題を解決するために使用しabcdc.com.netていますabcdc.com

についても懸念があるwww.場合は、明示的に確認する必要があります。

if url.startswith("www."):
   url = url.replace("www.","", 1)

1置換は、次のような奇妙なエッジケース用です www.net.www.com

あなたのURLがそれよりもワイルドになったら、人々が応答した正規表現の回答を見てください。


1

次のように、組み込みのrstrip関数を使用しました。

string = "test.com"
suffix = ".com"
newstring = string.rstrip(suffix)
print(newstring)
test

悪いアイデア。お試しください"test.ccom"
Shital Shah

しかし、これは問題のポイントではありません。既知の部分文字列を別の文字列の最後から削除するように要求されただけです。これは期待どおりに機能します。
アレックス

1

あなたは分割を使うことができます:

'abccomputer.com'.split('.com',1)[0]
# 'abccomputer'

5
ときにa = 'www.computerbugs.com'この結果を'www"
yairchu


0

Python> = 3.9:

'abcdc.com'.removesuffix('.com')

Python <3.9:

def remove_suffix(text, suffix):
    if text.endswith(suffix):
        text = text[:-len(suffix)]
    return text

remove_suffix('abcdc.com', '.com')

1
Python 3.9に対するあなたの答えは、上記のこの答えの複製です。以前のバージョンの回答もこのスレッドで何度も回答されており、文字列にサフィックスがない場合は何も返しません。
ザビエルギホ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.