web-dev-qa-db-ja.com

Python-左と右の境界が与えられている部分文字列を抽出する最もエレガントな方法

文字列があります-Python:

string = "/foo13546897/bar/Atlantis-GPS-coordinates/bar457822368/foo/"

予想される出力は次のとおりです。

"Atlantis-GPS-coordinates"

期待される出力は常に左側の「/ bar /」と右側の「/」で囲まれていることを知っています。

"/bar/Atlantis-GPS-coordinates/"

提案されたソリューションは次のようになります。

a = string.find("/bar/")
b = string.find("/",a+5)
output=string[a+5,b]

これは機能しますが、私はそれが好きではありません。誰かが美しい機能やヒントを知っていますか?

10
Vincent

split を使用できます:

>>> string.split("/bar/")[1].split("/")[0]
'Atlantis-GPS-coordinates'

1の最大分割を追加することによるいくつかの効率性

>>> string.split("/bar/", 1)[1].split("/", 1)[0]
'Atlantis-GPS-coordinates'

または partition を使用します:

>>> string.partition("/bar/")[2].partition("/")[0]
'Atlantis-GPS-coordinates'

または正規表現:

>>> re.search(r'/bar/([^/]+)', string).group(1)
'Atlantis-GPS-coordinates'

あなたとあなたのデータに話しかけるものに依存します。

15
dawg

あなたが持っていないのはそれほど悪いことではありません。私はそれを次のように書きます:

start = string.find('/bar/') + 5
end = string.find('/', start)
output = string[start:end]

あなたがそれを知っている限り/bar/WHAT-YOU-WANT/は常に存在します。そうでなければ、私は 正規表現のナイフ に手を伸ばすでしょう:

>>> import re
>>> PATTERN = re.compile('^.*/bar/([^/]*)/.*$')
>>> s = '/foo13546897/bar/Atlantis-GPS-coordinates/bar457822368/foo/'
>>> match = PATTERN.match(s)
>>> match.group(1)
'Atlantis-GPS-coordinates'
4
D.Shawley
import re

pattern = '(?<=/bar/).+?/'
string = "/foo13546897/bar/Atlantis-GPS-coordinates/bar457822368/foo/"

result = re.search(pattern, string)
print string[result.start():result.end() - 1]
# "Atlantis-GPS-coordinates" 

これはPython 2.xの例です。最初に行うことは次のとおりです:1.(?<=/bar /)は、これに先行する場合(/ bar /その前にある必要があります)2.「。+?/」は、次の「/」文字までの任意の文字数を意味します

それが一部に役立つことを願っています。

この種の検索をまとめて行う必要がある場合は、パフォーマンスを高めるためにこの検索を「コンパイル」することをお勧めしますが、一度だけ実行する必要がある場合は、気にしないでください。

1
crajun

reの使用(他のソリューションより遅い):

>>> import re
>>> string = "/foo13546897/bar/Atlantis-GPS-coordinates/bar457822368/foo/"
>>> re.search(r'(?<=/bar/)[^/]+(?=/)', string).group()
'Atlantis-GPS-coordinates'
0
heemayl