次の文字列を見てみましょう:「インターネット上のマーケティングとクリケット」。
正規表現を使用して、「Ma」-任意のテキスト-「et」のすべての可能な一致を見つけたいと思います。そう..
- 市場
- マーケティングとクリケット
- インターネットでのマーケティングとクリケット
正規表現Ma.*et
は「インターネット上のマーケティングとクリケット」を返します。正規表現Ma.*?et
は Market を返します。しかし、3つすべてを返す正規表現が欲しいのですが、それは可能ですか?
ありがとう。
次の文字列を見てみましょう:「インターネット上のマーケティングとクリケット」。
正規表現を使用して、「Ma」-任意のテキスト-「et」のすべての可能な一致を見つけたいと思います。そう..
正規表現Ma.*et
は「インターネット上のマーケティングとクリケット」を返します。正規表現Ma.*?et
は Market を返します。しかし、3つすべてを返す正規表現が欲しいのですが、それは可能ですか?
ありがとう。
私の知る限り:いいえ。
ただし、最初に非貪欲に一致させてから、量指定子を使用して新しい正規表現を生成し、2 番目の一致を取得することができます。このような:
Ma.*?et
Ma.{3,}?et
...等々...
みんなありがとう、それは本当に助けになりました。これが私がPHPのために思いついたものです:
function preg_match_ubergreedy($regex,$text) {
for($i=0;$i<strlen($text);$i++) {
$exp = str_replace("*","{".$i."}",$regex);
preg_match($exp,$text,$matches);
if($matches[0]) {
$matched[] = $matches[0];
}
}
return $matched;
}
$text = "Marketing and Cricket on the Internet";
$matches = preg_match_ubergreedy("@Ma.*?et@is",$text);
残念ながら、これは標準の POSIX 正規表現では実行できません。これは、単一の (正規表現ルールごとに最適な候補) 一致を返します。このタスクを実行するには、この正規表現をプログラムで使用していると仮定して、この正規表現を使用している特定のプログラミング言語に存在する可能性がある拡張機能を利用する必要があります。
より一般的な正規表現の場合、別のオプションとして、貪欲な正規表現を前の一致に対して再帰的に一致させ、最初と最後の文字を順番に破棄して、前の一致の部分文字列のみを一致させるようにすることもできます。が一致した後、サブマッチについてとのMarketing and Cricket on the Internet
両方をテストします。arketing and Cricket on the Internet
Marketing and Cricket on the Interne
C# ではこのようになります...
public static IEnumerable<Match> SubMatches(Regex r, string input)
{
var result = new List<Match>();
var matches = r.Matches(input);
foreach (Match m in matches)
{
result.Add(m);
if (m.Value.Length > 1)
{
string prefix = m.Value.Substring(0, m.Value.Length - 1);
result.AddRange(SubMatches(r, prefix));
string suffix = m.Value.Substring(1);
result.AddRange(SubMatches(r, suffix));
}
}
return result;
}
ただし、このバージョンでは、同じサブマッチが数回返される可能性があります。たとえば、最初は のサブマッチとして、次にのサブマッチとしてMarmoset
で 2 回検出されます。Marketing and Marmosets on the Internet
Marketing and Marmosets on the Internet
Marmosets on the Internet