私は文字列を持っています
$test = 'xyz45sd2-32d34-sd23-456562.abc.com'
目的は、$1 = 23 と $2 = 45 を取得することです。つまり、最後の の両側の桁数が等しくなり-
ます。桁数は可変であり、必ずしも 2 であるとは限りません。
私は次のことを試しました:
$test1 =~ s/.*(\d+)-(\d+).*//;
しかし
- $1 には 3 が含まれます
- $2 には 456562 が含まれます
この正規表現を試すことができます
if($test1 =~ m/(\S+)-(\S+)-([a-z]*)(\d+)-(\d\d)(\d+).*/)
{
print $4,"|",$5;
}
456562 からの最初の 2 ディジットだけが必要であると仮定します
この他のエントリは、正規表現がカウントされないことを確認します: How to match word where count of characters same
GreatBigBore のアイデアに基づいて、カウントに上限がある場合は、or 演算子 | を試すことができます。これは、一致を見つけるための要件にのみ一致します。一致した数に応じて、一致は異なるビンになります。それらを $1 と $2 に正しく配置するのは 1 つのケースだけです。
(\d{3})-(\d{3})|(\d{2})-(\d{2})|(\d{1})-(\d{1})
ただし、結果キャプチャを $1$3$5 と $2$4$6 として連結すると、探していた 2 つの文字列を効果的に取得できます。
別のアイデアは、繰り返し操作することです。一致が失敗するまで数を増やして、文字列の検索を繰り返すことができます。 (\d{1})-(\d{1})
、(\d{2})-(\d{2})
...
二分探索が頭に浮かび、O{ln(N)} になります。N はキャプチャの長さの上限です。
あなたが探しているものは、正規表現を使用することはできません。
正規表現 (その名前が示すように) は正規言語(チョムスキー階層Type-3 grammars
)のコンパクトな表現です。
ある種のカウント ( beginning
and以外のコンテキスト情報end
) を維持する式を書き出そうとしているため、正規表現を使用して探しているものは使用できません。この種の動作は、 DFA (実際にはすべての有限オートマトン)としてモデル化することはできません。a かどうかの非公式な証拠は、language
その言語を受け入れるDFAregular
が存在することです。この種のコンテキスト情報はDFAでモデル化できないため、矛盾して、問題の正規表現を書くことはできません。
my ($lhs,$rhs) = $test =~ /^[^-]+-[^-]+-([^-]+)-([^-.]+)\S+/;
# Alernatively and faster
my (undef,undef,$lhs,$rhs) = split /-/, $test;
# Rest is common, no matter how $lhs and $rhs is extracted.
my @left = reverse split //, $lhs;
my @right = split //, $rhs;
my $i;
for($i=0; exists($left[$i]) and exists($right[$i]) and $left[$i] =~ /\d/ and $right[$i] =~ /\d/ ; ++$i){}
--$i;
$lhs= join "", reverse @left[0..$i];
$rhs= join "", @right[0..$i];
print $lhs, "\t", $rhs, "\n";
編集:正規表現を使用して、 、 、およびの代わりに$lhs
およびの必要な数値部分を抽出することにより、私のソリューションを改善することができます。$rhs
split
reverse
for
perl -e '"xyz45sd2-32d34-sd23-456562.abc.com" =~ /(\d{2})-(\d{2})\d*(?=\.)/; print "$1\n$2\n"'