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

而不是现在这样做: 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这也应该像或%$1d正确地解析复合格式说明符。

于 2009-09-25T18:12:44.527 回答