3

条件付きでフィールドを抽出するには、Python 風味の正規表現を作成する必要があります。以下は、抽出する必要がある 2 種類のテスト文字列です。

 http://domain/string1/path/field_to_extract/path/filename
 http://domain/string2/path/90020_10029/path/filename

以下は私の要件です:

  1. string2 については、スラッシュ (/) と (_) の間の 4 番目の位置の数字のみを選択する必要があります。
  2. それ以外の場合は、4 番目のスラッシュ (/) の間のテキスト全体を選択する必要があります。

私は次の正規表現を書きました:

(?i)^(?:[^ ]*(?: {1,2})){6}(?:[a-z]+://)(?:[^ /:]+[^ /]/:]+[^ /]+/[^ /]+/)?(?:[^ /]+/){2}(?P<field_name>(?<=/string2/)(?:[^/]+/)([^_]+)|((?<!/string2/)(?:[^/]+/)([^/]+)))

条件付き抽出は正常に機能しているように見えますが、この正規表現は、抽出されるフィールドの前の文字列にも一致します。たとえば、最初のテスト文字列で使用すると、この正規表現は一致path/field_to_extractし、2 番目のテスト文字列では と一致しpath/90020ます。

必須フィールドの前にグループに無視を追加しましたが、機能していないようです。

正規表現を正しくするのを手伝ってください。

4

3 に答える 3

0

純粋なregex解決策:

import re

urls = [
    r'''http://domain/string1/path/field_to_extract/path/filename''',
    r'''http://domain/string2/path/90020_10029/path/filename'''
]

for url in urls:
    print(re.search(r'(?<![:/])/(?:(string2)|[^/]*)/[^/]*/((?(1)[^_]*|[^/]*))', url).group(2))

説明:

(?<![:/])/:: 別のスラッシュまたはコロンの後に続かないスラッシュを検索します。

(?:(string2)|[^/]*)/:: リテラル "string2" またはその他のものに一致します。それが最初のものである場合は、それを group-1 として保存して、後で条件付きの yes-no-パターンを実行します。

[^/]*/:: パスの 2 番目の部分に一致します。面白くない。

((?(1)[^_]*|[^/]*))_:: group-1 が存在する場合、最初( )まで一致し[^_]*ます。それ以外の場合は、次のスラッシュ ( [^/]*) まで一致します。

次の結果が得られます。

field_to_extract
90020
于 2013-08-27T08:58:41.593 に答える