1

moinmoinテキスト形式のファイルがあります。

* [[  Virtualbox Guest Additions]] (2011/10/17 15:19)
* [[  Abiword Wordprocessor]] (2010/10/27 20:17)
* [[  Sylpheed E-Mail]] (2010/03/30 21:49)
* [[   Kupfer]] (2010/05/16 20:18)

'[['と']]'の間のすべての単語は、エントリの簡単な説明です。エントリ全体を抽出する必要がありますが、個々の単語を抽出する必要はありません。

私はここで同様の質問に対する答えを見つけました:https ://stackoverflow.com/a/2700749/819596 しかし答えを理解することができません:"my @array = $str =~ /( \{ (?: [^{}]* | (?0) )* \} )/xg;"

うまくいくものは何でも受け入れられますが、説明は大いに役立ちます。つまり、何をするか、何をする(?0)/xgです。

4

7 に答える 7

2

コードはおそらく次のようになります。

use warnings; 
use strict;

my @subjects; # declaring a lexical variable to store all the subjects
my $pattern = qr/ 
  \[ \[    # matching two `[` signs
  \s*      # ... and, if any, whitespace after them
  ([^]]+) # starting from the first non-whitespace symbol, capture all the non-']' symbols
  ]]
/x;

# main processing loop:
while (<DATA>) { # reading the source file line by line
  if (/$pattern/) {      # if line is matched by our pattern
    push @subjects, $1;  # ... push the captured group of symbols into our array
  }
}
print $_, "\n" for @subjects; # print our array of subject line by line

__DATA__
* [[  Virtualbox Guest Additions]] (2011/10/17 15:19)
* [[  Abiword Wordprocessor]] (2010/10/27 20:17)
* [[  Sylpheed E-Mail]] (2010/03/30 21:49)
* [[   Kupfer]] (2010/05/16 20:18)

私が見るように、あなたが必要とするものは次のように説明することができます:ファイルの各行でこの記号のシーケンスを見つけてみてください...

[[, an opening delimiter, 
then 0 or more whitespace symbols,
then all the symbols that make a subject (which should be saved),
then ]], a closing delimiter

ご覧のとおり、この説明は非常に自然に正規表現に変換されます。おそらく必要ないのは/x正規表現修飾子だけです。これにより、広範囲にコメントすることができました。)。

于 2012-09-04T20:48:05.140 に答える
2

テキストに が含まれない場合は]、以前に推奨されていたように、次を使用できます。

/\[\[ ( [^\]]* ) \]\]/x

以下は]、含まれているテキストを許可しますが、より大きなパターンに組み込むことはお勧めしません。

/\[\[ ( .*? ) \]\]/x

以下は]、含まれているテキストで許可されており、最も堅牢なソリューションです。

/\[\[ ( (?:(?!\]\]).)* ) \]\]/x

例えば、

if (my ($match) = $line =~ /\[\[ ( (?:(?!\]\]).)* ) \]\]/x) {
   print "$match\n";
}

また

my @matches = $file =~ /\[\[ ( (?:(?!\]\]).)* ) \]\]/xg;

  • /x: パターン内の空白を無視します。パターンの意味を変えずに、パターンを読みやすくするためにスペースを追加できます。perlreに文書化されています。
  • /g: すべての一致を検索します。perlopに文書化されています。
  • (?0)リンクされたノードはカーリーの任意のネストを処理する必要があったため、パターンを再帰的にするために使用されました。* /g: すべての一致を検索します。perlreに文書化されています。
于 2012-09-04T21:18:55.290 に答える
1

モジュールText::Balancedから「extract_bracketed」または「extract_delimited」を使用することをお勧めします-ここを参照してください:http://perldoc.perl.org/Text/Balanced.html

于 2012-09-05T06:17:48.360 に答える
1
\[\[(.*)]]

\[はリテラル[、 ]はリテラル]であり .*、0以上の文字のすべてのシーケンスを意味し、括弧で囲まれたものはキャプチャグループであるため、スクリプトの後半で$ 1(またはグループの数に応じて$ 2 .. $ 9)でアクセスできます。あなたが持っている)。

すべてをまとめると、2つに一致[し、最後に2つ連続して発生するまでのすべてが一致します]

更新 あなたの質問を2回目に読んだときに、突然混乱しました。[[と]]の間のコンテンツが必要ですか、それとも行全体が必要ですか。その場合は、括弧を完全に省略して、パターンが一致するかどうかをテストするだけで、キャプチャする必要はありません。 。

于 2012-09-04T20:48:18.690 に答える
1
perl -pe 's/.*\[\[(.*)\]\].*/\1/g' temp

以下でテスト:

> cat temp
        * [[  Virtualbox Guest Additions]] (2011/10/17 15:19)
        * [[  Abiword Wordprocessor]] (2010/10/27 20:17)
        * [[  Sylpheed E-Mail]] (2010/03/30 21:49)
        * [[   Kupfer]] (2010/05/16 20:18)
>
> perl -pe 's/.*\[\[(.*)\]\].*/\1/g' temp
  Virtualbox Guest Additions
  Abiword Wordprocessor
  Sylpheed E-Mail
   Kupfer
>
  • s/. [[(. )]].*/\1/g
  • .*[[-> [[ まで任意の文字に一致
  • (.*)]] 文字列 "[[" から "]]" の後の任意の文字を \1 に保存します
  • .*-> 行の残りの部分に一致します。

\1 にデータがあるので、コンソールでの印刷に使用できます。

于 2012-09-05T13:59:38.940 に答える
1

あなたが見つけた答えは、再帰的なパターンマッチングのためのもので、必要ないと思います。

  • /x 正規表現で無意味なスペースとコメントを使用できます。

  • /g は、すべての文字列に対して正規表現を実行します。それがなければ、最初の試合までしか実行されません。

  • /xg は /x と /g を組み合わせたものです。

  • (?0) 正規表現自体を再度実行します (再帰)

わかりましたら、次のようなものが必要です。

$text="* [[  Virtualbox Guest Additions]] (2011/10/17 15:19)
* [[  Abiword Wordprocessor]] (2010/10/27 20:17)
* [[  Sylpheed E-Mail]] (2010/03/30 21:49)
* [[   Kupfer]] (2010/05/16 20:18)
";

@array=($text=~/\[\[([^\]]*)\]\]/g);
print join(",",@array);

# this prints "  Virtualbox Guest Additions,  Abiword Wordprocessor,  Sylpheed E-Mail,   Kupfer"
于 2012-09-04T21:10:10.287 に答える
0
my @array = $str =~ /( \{ (?: [^{}]* | (?0) )* \} )/xg;

「x」フラグは、より読みやすい表現を可能にするために、正規表現で空白が無視されることを意味します。'g' フラグは、結果が左から右へのすべての一致のリストになることを意味します (*g*lobally に一致)。

(?0)、括弧の最初のグループ内の正規表現を表します。これは再帰的な正規表現であり、次のような一連の規則と同等です。

E := '{' ( NoBrace | E) '}'
NoBrace := [^{}]* 
于 2012-09-04T20:58:56.477 に答える