AutoLink用の正規表現について、 「正規表現の中で空白やコメント文を使用できるようにする」ためのオプション 'x'(PCRE_EXTENDED) を使用しているため、それらを適切にエスケープしないとうまく動作しないケースがある事がわかりました。
(1.4.3)
(1.4.8)
autolink.dat のスペースをエスケープしたらOKそうでした。
autolink.dat
...|InterWikiテクニカル|Wen Jiabao|ヘルプ|整形ルール|日本語) ...|InterWikiテクニカル|Wen\ Jiabao|ヘルプ|整形ルール|日本語)
-$result .= str_replace(' ','\\ ',preg_quote(substr($pages[$i],$pos),'/')); +$result .= str_replace(' ','\\ ',preg_quote(mb_substr($pages[$i],$pos),'/'));
AutoAlias 導入前は、ページ名に# が使えないこともあって、generate_trie_regex 関数が# をエスケープしていなくても問題がありませんでした。
しかし、[[#01>test/01]] のように*1 別名に# を含むAutoAlias 設定をすると、AutoAlias の正規表現にエスケープされていない# が現れ、
InlineConverter クラスで使用する際にパターン修飾子x (PCRE_EXTENDED) によって# 以降がコメント扱いされて正規表現に不整合が発生し、エラーとなります。
generate_trie_regex 関数を
if ($index < ($i - 1)) { // Some more keys found // Recurse $regex .= str_replace(array(' ','#'), array('\\ ','\\#'), preg_quote($char, '/')) . generate_trie_regex($array, $index, $i, $pos + 1); } else { // Not found $regex .= str_replace(array(' ','#'), array('\\ ','\\#'), preg_quote(mb_substr($array[$index], $pos), '/')); }
として# もエスケープするようにすると、正常に表示されるようになりました。 -- 名無しさん 2009-03-20 (金) 00:21:26
+// preg_quote(), and also escape PCRE_EXTENDED-related chars +// REFERENCE: http:// www.php.net/manual/en/reference.pcre.pattern.modifiers.php +// NOTE: Some special whitespace characters may warned by PCRE_EXTRA +// because of mismatch-possibility between PCRE_EXTENDED and '[:space:]#'. +function preg_quote_extended($string, $delimiter = NULL) +{ + // Escape some more chars + $regex_from = '/([[:space:]#])/'; + $regex_to = '\\\\$1'; + + if (is_string($delimiter) && preg_match($regex_from, $delimiter)) { + $delimiter = NULL; + } + + return preg_replace($regex_from, $regex_to, preg_quote($string, $delimiter)); +} + // Generate one compact regex for quick reTRIEval, // that just matches with all $array-values. // @@ -647,13 +663,11 @@ if ($index < ($i - 1)) { // Some more keys found // Recurse - $regex .= str_replace(' ', '\\ ', preg_quote($char, '/')) . + $regex .= preg_quote_extended($char, '/') . generate_trie_regex($array, $index, $i, $pos + 1); } else { // Not found - $regex .= str_replace(' ', '\\ ', - preg_quote(mb_substr($array[$index], $_pos), '/')); + $regex .= preg_quote_extended(mb_substr($array[$index], $_pos), '/'); } $index = $i; }
こうなる部分は (?:1(?:0|1|2|3|4|5|6|7|8|9)|2(?:0|1|2|3|4|5|6|7|8|9)) 本来こうできる [12][0-9]