1

次のような文字列を取得\input{{whatever}{1}}\mypath{{path1}{path2}{path3}...{pathn}}\shape{{0.2}{0.3}} します: すべてのパスをキャプチャしたいと思います: path1、path2、... pathn。re私はPythonでモジュールを試しました。ただし、複数のキャプチャはサポートしていません。例:r"\\mypath\{(\{[^\{\}\[\]]*\})*\}"最後に一致したグループのみを返します。パターンを適用すると、次のようsearch(r"\mypath{{path1}{path2}})"にのみ返さgroups()れます("{path2}",)

次に、これを行う別の方法を見つけました。

    gpathRegexPat=r"(?:\\mypath\{)((\{[^\{\}\[\]]*\})*)(?:\})"
    gpathRegexCp=re.compile(gpathRegexPat)
    strpath=gpathRegexCp.search(r'\mypath{{sadf}{ad}}').groups()[0]
    >>> strpath
    '{sadf}{ad}'
    p=re.compile('\{([^\{\}\[\]]*)\}')
    >>> p.findall(strpath)
    ['sadf', 'ad']

また:

    >>> gpathRegexPat=r"\\mypath\{(\{[^{}[\]]*\})*\}"
    >>> gpathRegexCp=re.compile(gpathRegexPat, flags=re.I|re.U)
    >>> strpath=gpathRegexCp.search(r'\input{{whatever]{1}}\mypath{{sadf}{ad}}\shape{{0.2}{0.1}}').group()
    >>> strpath
    '\\mypath{{sadf}{ad}}'
    >>> p.findall(strpath)
    ['sadf', 'ad']

この時点で、元の文字列に対して findall を使用しないのはなぜでしょうか? 私は使用するかも しれませんgpathRegexPat=r"(?:\\mypath\{)(?:\{[^\{\}\[\]]*\})*?\{([^\{\}\[\]]*)\}(?:\{[^\{\}\[\]]*\})*?(?:\})": 最初のマッチが 1 回、2 番目のマッチが 0 回の場合、キャプチャします。ただし、この正規表現でのみ返されます。(?:\{[^\{\}\[\]]*\})*?(?:\{[^\{\}\[\]]*\})*?sadf(?:\{[^\{\}\[\]]*\})*?ad['sadf']

これらすべての余分なパターン ((?:\\mypath\{)および(?:\})) がなくても、実際には機能します。

    >>> p2=re.compile(r'(?:\{[^\{\}\[\]]*\})*?\{([^\{\}\[\]]*)\}(?:\{[^\{\}\[\]]*\})*?')
    >>> p2.findall(strpath)
    ['sadf', 'ad']
    >>> p2.findall('{adadd}{dfada}{adafadf}')
    ['adadd', 'dfada', 'adafadf']

誰かが私にこの動作を説明できますか? 私が望む結果を達成するためのよりスマートな方法はありますか?

4

2 に答える 2

2
re.findall("{([^{}]+)}",text)

動作するはずです

戻り値

['path1', 'path2', 'path3', 'pathn']

最後に

my_path = r"\input{{whatever}{1}}\mypath{{path1}{path2}{path3}...{pathn}}\shape{{0.2}{0.3}}"
#get the \mypath part
my_path2 = [p for p in my_path.split("\\") if p.startswith("mypath")][0]
print re.findall("{([^{}]+)}",my_path2)

またはさらに良い

re.findall("{(path\d+)}",text) #will only return things like path<num> inside {}
于 2012-09-28T13:38:55.117 に答える
1

あなたが正しいです。グループ内で繰り返されるサブグループを返すことはできません。必要なことを行うには、正規表現を使用してグループをキャプチャし、次に 2 番目の正規表現を使用して繰り返されるサブグループをキャプチャします。

この場合、次のようになります\\mypath{(?:\{.*?\})}。これは戻ります{path1}{path2}{path3}

次に、{pathn}その文字列内の繰り返しパターンを見つけるには、単純に\{(.*?)\}. これは、中かっこのあるものに一致します。はの.*?貪欲でないバージョンです.*。つまり、可能な最長の一致ではなく、可能な限り短い一致を返します。

于 2012-09-28T13:38:18.487 に答える