0

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'
)

Array ( 0 => '%%%c' ) つまり、カスタム printf の処理を​​行った後にピースを結合するために、トークン化されていても、入力をそのままにしておく必要があります。入力で遭遇するフォーマット。

ありがとう、

フラウィウス

PS: 「ユーザー」は実際には別のプログラマーです。私はセキュリティへの影響を認識しています。

4

2 に答える 2

1

必要なのが % の後に文字または別の % が続く場合は、次のように簡単に実行できます。

$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"%%%

于 2009-09-25T17:09:21.943 に答える
1

コード:

$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これにより、 orのような複合フォーマット指定子%$1dも適切に解析されるはずです。

于 2009-09-25T18:12:44.527 に答える