分割の魔法。私の最初の仮定は技術的に正しくありませんでした (解決策は簡単に得られますが)。それでは、分割パターンを確認しましょう。
(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)
ちょっとアレンジし直しました。外側の括弧は必要ありません。最後に、単一の文字を文字クラスに移動しました。
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|[\/._=?&%+-]
それは、事前にソートするためのものです。s
このパターンを分割パターンと呼び、定義しましょう。
split-at パターンのこれらの文字以外のすべての部分と、少なくとも 3 文字を一致させる必要があります。
正しい分割シーケンスのサポートと Unicode サポートを含む、次のパターンでこれを実現できました。
$pattern = '/
(?(DEFINE)
(?<s> # define subpattern which is the split pattern
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|
[\\/._=?&%+-] # a little bit optimized with a character class
)
)
(?:(?&s)) # consume the subpattern (URL starts with \/)
\K # capture starts here
(?:(?!(?&s)).){3,} # ensure this is not the skip pattern, take 3 characters minimum
/ux';
または小さい:
$path = '/2009/06/pagerank-update.htmltesthtmltest%C3%A4shtml';
$subject = urldecode($path);
$pattern = '/(?(DEFINE)(?<s>html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|[\\/._=?&%+-]))(?:(?&s))\K(?:(?!(?&s)).){3,}/u';
$word_array = preg_match_all($pattern, $subject, $m) ? $m[0] : [];
print_r($word_array);
結果:
Array
(
[0] => 2009
[1] => pagerank
[2] => update
[3] => test
[4] => testä
)
同じ原理を使用することもできますpreg_split
。少し違います:
$pattern = '/
(?(DEFINE) # define subpattern which is the split pattern
(?<s>
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|
[\/._=?&%+-]
)
)
(?:(?!(?&s)).){3,}(*SKIP)(*FAIL) # three or more is okay
|(?:(?!(?&s)).){1,2}(*SKIP)(*ACCEPT) # two or one is none
|(?&s) # split @ split, at least
/ux';
使用法:
$word_array = preg_split($pattern, $subject, 0, PREG_SPLIT_NO_EMPTY);
結果:
Array
(
[0] => 2009
[1] => pagerank
[2] => update
[3] => test
[4] => testä
)
これらのルーチンは要求どおりに機能します。しかし、これにはパフォーマンスと価格があります。コストは古い回答と同様です。
関連する質問:
古い答え、2段階の処理を行う(最初の分割、次にフィルタリング)
分割ルーチンを使用しているため、長さに関係なく分割されます。
したがって、できることは、結果をフィルタリングすることです。正規表現 ( preg_filter
) を使用して、これをもう一度行うことができます。たとえば、小さい 3 文字をすべて削除するものです。
$word_array = preg_filter(
'/^.{3,}$/', '$0',
preg_split(
'/(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)/',
urldecode($path),
NULL,
PREG_SPLIT_NO_EMPTY
)
);
結果:
Array
(
[0] => 2009
[2] => pagerank
[3] => update
)