web-dev-qa-db-ja.com

Perlで複数のパターンを持つ文字列を分割する方法は?

複数のパターンで文字列を分割したい:

例.

my $string= "10:10:10, 12/1/2011";

my @string = split(/firstpattern/secondpattern/thirdpattern/, $string);

foreach(@string) {
    print "$_\n";
}

次の出力が必要です。

10
10
10
12
 1
2011

これを行う適切な方法は何ですか?

14
quinekxi

正規表現の区切り文字で 文字クラス を使用して、可能な区切り文字のセットを照合します。

my $string= "10:10:10, 12/1/2011";
my @string = split /[:,\s\/]+/, $string;

foreach(@string) {
    print "$_\n";
}

説明

  • スラッシュのペア/.../は、照合する正規表現またはパターンを示します。

  • 角括弧のペア[...]は、正規表現の文字クラスを示します。

  • 内部には、一致する可能性のある文字のセットがあります:コロン:、カンマ,、任意のタイプのスペース文字\s、およびスラッシュ\/(エスケープ文字としてバックスラッシュを使用)。

  • +は、直前の1つ以上の文字(この場合は文字クラス全体)に一致する必要があります。これがないと、コンマスペースは2つの別々の区切り文字と見なされ、結果に空の文字列が追加されます。

32
stevenl

間違ったツール!

my $string = "10:10:10, 12/1/2011";
my @fields = $string =~ /([0-9]+)/g;
5
ikegami

非数字で分割できます。

#!/usr/bin/Perl
use strict;
use warnings;
use 5.014;

my $string= "10:10:10, 12/1/2011";
say for split /\D+/, $string;
3
Chris Charley

数値が必要な場合は、数値を抽出します。

my @numbers = $string =~ /\d+/g;
say for @numbers;

perlop で指定されているように、括弧をキャプチャする必要はありません:

/ g修飾子は、グローバルパターンマッチング、つまり文字列内で可能な限り多くの回数のマッチングを指定します。動作はコンテキストによって異なります。リストコンテキストでは、正規表現内のキャプチャ括弧に一致する部分文字列のリストを返します。 括弧がない場合は、パターン全体を括弧で囲んでいるかのように、一致したすべての文字列のリストを返します。

2
TLP
my $string= "10:10:10, 12/1/2011";

my @string = split(m[(?:firstpattern|secondpattern|thirdpattern)+], $string);

my @string = split(m[(?:/| |,|:)+], $string);

print join "\n", @string;
2
Trizen

元の質問に答えるために、あなたは探していた the |演算子

my $string = "10:10:10, 12/1/2011";

my @string = split(/:|,\s*|\//, $string);

foreach(@string) {
    print "$_\n";
}

しかし、他の答えが指摘するように、さらに単純化または一般化することで、多くの場合それを改善できます。

2
reinierpost

明らかに日付/時刻であるものを解析しているので、 DateTime :: Format :: Strptime を使用して日付時刻オブジェクトに解析する方が理にかなっているのではないかと思います。

1
Dave Cross