4

For the strings:

  • text::handle:e@ma.il::text
  • text::chat_identifier:chat0123456789&text

I have the current regex:

m/(handle:|chat_identifier:)(.+?)(:{2}|&)/

And I am currently using $2 in order to obtain the value I wish (in the first string e@ma.il and in the second, chat0123456789).

Is there a better/faster/simpler way to solve this problem, though?

4

4 に答える 4

4

「より良い」かどうかはコンテキストに依存しますが、次のアプローチを取ることができます。「:」で文字列を分割し、結果のリストの 4 番目の要素を取得します。3 番目のフィールドが「handle」または「chat_identifier」以外の値である場合、これは間違いなく正規表現よりも読みやすく、より堅牢です。

どちらのアプローチでも速度は非常に似ていると思いますが、おそらくperlのほとんどすべての実装で. 心配する前に、このステップでは速度が重要であることを示したいと思います...

于 2012-11-22T00:02:29.680 に答える
2

正規表現ソリューションの場合、これは少し単純であり、後戻りする必要はありません。

m/(handle|chat_identifier):([^:&]+)/

わずかな違いに注意してください: あなたのものは値内に単一のコロンを許可しますが、私のものは許可しません (最初に遭遇したコロンで停止します)。それが問題でない場合は、私のバリアントを使用できます。または、コメントで述べたように、分割し:て結果の 4 番目の要素を使用します。

二重コロンでのみ停止する同等のバージョンは次のとおりです。

m/(handle|chat_identifier):((?:(?!::|&).)+)/

それほど美しくはありませんが、バックトラックを回避します (ただし、先読みにより遅くなる可能性があります... 速度が重要な場合は、それをプロファイルする必要があります)。

于 2012-11-22T00:04:08.730 に答える
1

必要な値が常に同じ位置にあり、 と で安全に分割できる場合は:&おそらく次のようにするとうまくいきます。

use Modern::Perl;

say +( split /[:&]+/ )[2] for <DATA>;

__DATA__
text::handle:e@ma.il::text
text::chat_identifier:chat0123456789&text

出力:

e@ma.il
chat0123456789
于 2012-11-22T02:00:46.810 に答える