質問

vsprintf を使用する関数のカスタム形式をユーザーに指定させる必要があります。PHP には glibc の register_printf_function() がないため、PCRE を使用して行う必要があります。

私の質問は、後でプログラムで使用できる方法で、%の後に任意の文字が続き、その前に%がないものに一致する最適なREGEXPは何でしょうか?

私が得られた最も近い解決策は次のとおりでした。

<?php

function myprintf($format,$args) {
 $matches = array();
 preg_match_all('/((?<!%)%*[^%]+)/', $format,$matches,PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER);
 print_r($matches);
}

myprintf("begin%a%%b%%%c%d",NULL);

これはある程度機能しますが、「%%%c」のような入力によって「混乱」します。次のような一連の 2 つの % 記号 (つまり、エスケープ) を 1 つのグループに含めたいと考えています。

Array (
 0 => '%%',
 1 => '%c'
)

そして今それが行われているのとは異なります:アレイ(0 => '%% c')は、入力で遭遇するカスタムprintf形式の処理を行った後にピースを結合するために、トークン化されていますが、入力をそのままに保つ必要があります。

ありがとう、

フラヴィウス

追伸:「ユーザー」は実際には別のプログラマーです。セキュリティ上の影響については承知しています。

役に立ちましたか?

解決

コード:

$string = "begin%a%%b%%%c%d";
preg_match_all('/([^%]|%%)+|%.*?[a-zA-Z]/', $string, $matches);
print_r($matches[0]);

出力:

Array
(
    [0] => begin
    [1] => %a
    [2] => %%b%%
    [3] => %c
    [4] => %d
)

これは、次のような複合形式指定子を解析する必要があります。 %.3f または %$1d ちゃんと、それも。

他のヒント

% の後に文字または別の % が必要な場合は、次のようにするだけです。

$string = "begin%a%%b%%%c%d";
preg_match_all("/%./", $string, $matches);
$values = $matches[0];

// $values = array(5) { [0]=> string(2) "%a" [1]=> string(2) "%%" [2]=> string(2) "%%" [3]=> string(2) "%c" [4]=> string(2) "%d" }

// begin %a %% b %% %c %d <- is the string with spaces. 

編集:

これは、以下のコメントから求めているものと同等だと思います。

preg_match_all('/(\s?\w+\s?|%[^%]|%%)/', $string, $matches);
$value = $matches[0];

// $value = array(7) { [0]=> string(5) "begin" [1]=> string(2) "%a" [2]=> string(2) "%%" [3]=> string(1) "b" [4]=> string(2) "%%" [5]=> string(2) "%c" [6]=> string(2) "%d" }

主な違いは、 [2]=> string(3) "%%b" になる [2]=> string(2) "%%" [3]=> string(1) "b" 同じ結果が得られるはずです。 %% 単体として評価されるだろう % いずれかの方法。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top