3

正規表現が次のような場合、Perl 5 の正規表現を可能な限り長い文字列に一致させることができます。

a|aa|aaa

おそらくperl 6ではデフォルトですが、perl 5ではどうすればこの動作を得ることができますか?

例のパターン:

[0-9]|[0-9][0-9]|[0-9][0-9][0-9][0-9]

string がある場合2.10.2014、最初の一致は 2 になります。これで問題ありません。しかし、次の一致は 1 になり、10 になるはずなので、これは問題ありません。その後、2014 は 4 になり、その後 2,0,1,4 に一致しますが、[0-9][0-9] を使用すると 2014 になるはずです。 [0-9][0-9]。[0-9]+ を使用できることはわかっていますが、使用できません。

4

4 に答える 4

4

一般的な解決策: 最も長いものを最初に置きます。

my ($longest) = /(aaa|aa|a)/

具体的な解決策: 使用

my ($longest) = /([0-9]{4}|[0-9]{1,2})/

パターンを編集できない場合は、すべての可能性を見つけて、最も長いものを見つける必要があります。

my $longest;
while (/([0-9]|[0-9][0-9]|[0-9][0-9][0-9][0-9])/g) {
   $longest = $1 if length($1) > length($longest);
}
于 2013-02-23T01:53:26.920 に答える
2

未知のパターンに対して私が見ることができる最も健全な解決策は、可能なすべてのパターンに一致し、一致した部分文字列の長さを見て、最も長い部分文字列を選択することです:

my @patterns = (qr/a/, qr/a(a)/, qr/b/, qr/aaa/);
my $string = "aaa";

my @substrings = map {$string =~ /($_)/; $1 // ()} @patterns;

say "Matched these substrings:";
say for @substrings;

my $longest_token = (sort { length $b <=> length $a } @substrings)[0];

say "Longest token was: $longest_token";

出力:

Matched these substrings:
a
aa
aaa
Longest token was: aaa

既知のパターンの場合、最初の一致が最長の一致と同じになるように手動で並べ替えます。

"aaa" =~ /(aaa|aa|b|a)/;
say "I know that this was the longest substring: $1";
于 2013-02-23T01:57:30.583 に答える
2

代替は一致する最初の代替を使用するので、/aaa|aa|a/代わりに書くだけです。

質問で示した例については、私が言ったように、最も長い代替案を最初に置いてください。

[0-9][0-9][0-9][0-9]|[0-9][0-9]|[0-9]
于 2013-02-23T01:18:04.397 に答える