0

テキストを読み取り、正規表現を使用してパターンのすべてのインスタンスを検索し、一致する文字列を出力したいと考えています。re.search() メソッドを使用すると、目的のパターンの最初のインスタンスを正常に取得して出力できます。

import re

text = "Cello is a yellow parakeet who sings with Lillian. Toby is a clown who doesn't sing. Willy is a Wonka. Cello is a yellow Lillian."

match = re.search(r'(cello|Cello)(\W{1,80}\w{1,60}){0,9}\W{0,20}(lillian|Lillian)', text)
print match.group()

残念ながら、re.search() メソッドは目的のパターンの最初のインスタンスしか見つけられないため、re.findall() を置き換えました。

import re

text = "Cello is a yellow parakeet who sings with Lillian. Toby is a clown who doesn't sing. Willy is a Wonka. Cello is a yellow Lillian."

match = re.findall(r'(cello|Cello)(\W{1,80}\w{1,60}){0,9}\W{0,20}(lillian|Lillian)', text)
print match

このルーチンは、サンプル テキスト内のターゲット パターンの両方のインスタンスを検出しますが、パターンが発生する文を印刷する方法が見つかりません。この後者のコードの print 関数は、('Cello', 'with', 'Lillian'), ('Cello', 'yellow', 'Lillian') を生成します。リリアンと一緒に歌う黄色いインコ チェロは黄色いリリアンです。

この目的の出力を得るために、コードの 2 番目のビットを変更する方法はありますか? この質問に役立つアドバイスをいただければ幸いです。

4

2 に答える 2

3

説明

Cello と Lillian の両方を含む完全な文をキャプチャするこの正規表現のような前方参照を使用します。

(?:(?<=\.)\s+|^)((?=(?:(?!\.(?:\s|$)).)*?\b[Cc]ello(?=\s|\.|$))(?=(?:(?!\.(?:\s|$)).)*?\b[Ll]illian(?=\s|\.|$)).*?\.(?=\s|$))

ここに画像の説明を入力

式は、次の機能コンポーネントのように分解されます。

  • (?:(?<=\.)\s+|^).任意の数のスペースが続くa の後、または文字列の最初の to で、この文の一致を開始します
  • (この文全体をキャプチャするキャプチャ グループ 1 を開始します
  • (?=先読みを始める
    • (?:(?!\.(?:\s|$)).)*?正規表現エンジンがこの文を残さないように、.空白または文字列の終わりが続くことを強制的に確認する
    • \b単語 break に一致
    • [Cc]ello目的のテキストをすべて小文字または大文字の頭文字に一致させます
    • (?=\s|\.|$).文字列の末尾にスペース、 、または文字列の末尾があることを確認するために先読み
    • )先見の終わり
  • (?=(?:(?!\.(?:\s|$)).)*?\b[Ll]illian(?=\s|\.|$))これは本質的に同じことを行いますが、リリアンの場合は
  • .*?\.(?=\s|$)ピリオドまでの文の残りをキャプチャし、ピリオドの後に空白または文字列の末尾が続くことを確認します
  • )文末キャプチャグループ1

コード例

Python はよくわからないので、PHP の例を示します。match ステートメントで、式が改行文字と一致sするようにするオプションを使用していることに注意してください.

入力テキスト

Cello is a yellow parakeet who sings with Lillian. Toby is a clown who doesn't sing. Willy is a Wonka. Cello is a yellow Lillian.
Cello likes Lillian and kittens.
Lillian likes Cello and dogs.  Cello has no friends. And Lillian also hasn't met anyone.

コード

<?php
$sourcestring="your source string";
preg_match_all('/(?:(?<=\.)\s+|^)((?=(?:(?!\.(?:\s|$)).)*?\b[Cc]ello(?=\s|\.|$))(?=(?:(?!\.(?:\s|$)).)*?\b[Ll]illian(?=\s|\.|$)).*?\.(?=\s|$))/s',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>

マッチ

$matches Array:
(
    [0] => Array
        (
            [0] => Cello is a yellow parakeet who sings with Lillian.
            [1] =>  Cello is a yellow Lillian.
            [2] => 
Cello likes Lillian and kittens.
            [3] => 
Lillian likes Cello and dogs.
        )

    [1] => Array
        (
            [0] => Cello is a yellow parakeet who sings with Lillian.
            [1] => Cello is a yellow Lillian.
            [2] => Cello likes Lillian and kittens.
            [3] => Lillian likes Cello and dogs.
        )

)

文字列 Cello が Lillian の前にある文を絶対に一致させる必要がある場合は、次のような表現を使用します。ここでは、閉じ括弧を 1 つ移動しただけです。

(?:(?<=\.)\s+|^)((?=(?:(?!\.(?:\s|$)).)*?\b[Cc]ello(?=\s|\.|$)(?=(?:(?!\.(?:\s|$)).)*?\b[Ll]illian(?=\s|\.|$))).*?\.(?=\s|$))

ここに画像の説明を入力

入力テキスト

Cello is a yellow parakeet who sings with Lillian. Toby is a clown who doesn't sing. Willy is a Wonka. Cello is a yellow Lillian.
Cello likes Lillian and kittens.
Lillian likes Cello and dogs.  Cello has no friends. And Lillian also hasn't met anyone.

キャプチャ グループ 1 の出力

[1] => Array
    (
        [0] => Cello is a yellow parakeet who sings with Lillian.
        [1] => Cello is a yellow Lillian.
        [2] => Cello likes Lillian and kittens.
    )
于 2013-06-19T05:54:32.700 に答える
2

2 つのエンドポイントの周りに大きなキャプチャ グループを作成するだけです。

import re

text = "Cello is a yellow parakeet who sings with Lillian. Toby is a clown who doesn't sing. Willy is a Wonka. Cello is a yellow Lillian."

for match in re.findall(r'(Cello(?:\W{1,80}\w{1,60}){0,9}\W{0,20}Lillian)', text, flags=re.I):
    print match

これで、次の 2 つの文が得られます。

Cello is a yellow parakeet who sings with Lillian
Cello is a yellow Lillian

いくつかのヒント:

  • flags=re.I正規表現は大文字と小文字を区別しないため、とCelloの両方に一致します。celloCello
  • (?:foo)(foo)キャプチャされたテキストが一致として表示されないことを除いて、と同じです。一致させずにグループ化するのに便利です。
于 2013-06-19T03:02:57.027 に答える