PHP 中的 register_printf_function

发布于 2024-08-06 06:49:24 字数 754 浏览 2 评论 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”等输入“混淆”。我希望在一个分组中有一系列两个 % 符号(即转义),例如:

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

而不是像现在这样: 大批 ( 0 => '%%%c' ) 也就是说,尽管已标记化,但我需要保持输入完整,以便在处理输入中遇到的自定义 printf 格式后将各个部分连接在一起。

谢谢,

Flavius

PS:“用户”实际上是另一个程序员。我了解安全隐患。

I need to let the user specify a custom format for a function which uses vsprintf, and since PHP doesn't have glibc' register_printf_function(), I'll have to do it with PCRE.

My question is, what would be the best REGEXP to match % followed by any character and not having % before it, in an usable manner for programmatic use afterwards?

The closest solution I could get was:

<?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);

Which kinda works, BUT this gets "confused" by inputs like "%%%c". I would like to have series of two %-signs (that is, escaped) in one grouping, like:

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

and not like it's doing it now:
Array (
0 => '%%%c'
)
That is, I need to keep the input intact, though tokenized, in order to join the pieces together after I do the processing of the custom printf formats I encounter in the input.

Thanks,

Flavius

PS: the "user" is actually another programmer. I am aware of the security implications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滥情哥ㄟ 2024-08-13 06:49:24

代码:

$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

Code:

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

Output:

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

This should parse compound format specifiers like %.3f or %$1d properly as well, also.

别忘他 2024-08-13 06:49:24

如果您想要的是一个 % 后跟一个字母或另一个 %,那么您可以简单地执行以下操作:

$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]=>;字符串(2) "%%" [3]==> string(1) "b" 应该会给出相同的结果,因为 %% 无论如何都会被评估为单个 %

If what you want is a % followed by a letter or another % then you can simply do:

$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. 

Edit:

I think this is equivalent to what you want from the comments below:

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" }

The main difference is that [2]=> string(3) "%%b" becomes [2]=> string(2) "%%" [3]=> string(1) "b" which should give you the same results because the %% would be evaluated as a single % anyways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文