Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在运行之前检查vsprintf的参数数是否正确_Php_Regex_Printf - Fatal编程技术网

Php 如何在运行之前检查vsprintf的参数数是否正确

Php 如何在运行之前检查vsprintf的参数数是否正确,php,regex,printf,Php,Regex,Printf,我试图使用vsprintf()输出格式化字符串,但在运行它之前,我需要验证参数的数量是否正确,以防止出现“参数太少”的错误 本质上,我认为我需要的是一个正则表达式来计算类型说明符的数量,但对于正则表达式来说,我是非常无用的,我无法在任何地方为它提供资金,所以我想我应该试一试。:) 除非你能想出更好的方法,否则这个方法就是我想要的 function __insertVars($string, $vars = array()) { $regex = ''; $total_req =

我试图使用vsprintf()输出格式化字符串,但在运行它之前,我需要验证参数的数量是否正确,以防止出现“参数太少”的错误

本质上,我认为我需要的是一个正则表达式来计算类型说明符的数量,但对于正则表达式来说,我是非常无用的,我无法在任何地方为它提供资金,所以我想我应该试一试。:)

除非你能想出更好的方法,否则这个方法就是我想要的

function __insertVars($string, $vars = array()) {

    $regex = '';
    $total_req = count(preg_match($regex, $string));

    if($total_req === count($vars)) {
        return vsprintf($string, $vars);
    }

}

请告诉我您是否能想出一种更简单的方法。

我认为您的解决方案是或多或少可靠地判断字符串中有多少个参数的唯一方法

下面是我提出的正则表达式,将其与
preg\u match\u all()一起使用。

基于。应与PHP 4.0.6+/5兼容


编辑-更紧凑的版本:

%[-+]?(?:[ 0]|'.)?a?\d*(?:\.\d*)?[%bcdeEufFgGosxX]
另外,利用代码中的
func\u get\u args()
func\u num\u args()
函数


编辑:-已更新以支持位置/交换参数(未测试):


我使用了Alix Axel answer并创建了通用函数

我们有一个
$countArgs
(来自函数参数)和
$countVariables
(来自
$format
类似
%s

例如:

$object->format('Hello, %s!', ['Foo']); // $countArgs = 1, $countVariables = 1;
你好,福

$object->format('Hello, %s! How are you, %s?', ['Bar']); // $countArgs = 1, $countVariables = 2;
打印:错误

功能:

public static function format($format, array $args)
{
    $pattern = "~%(?:(\d+)[$])?[-+]?(?:[ 0]|['].)?(?:[-]?\d+)?(?:[.]\d+)?[%bcdeEufFgGosxX]~";

    $countArgs = count($args);
    preg_match_all($pattern, $format, $expected);
    $countVariables = isset($expected[0]) ? count($expected[0]) : 0;

    if ($countArgs !== $countVariables) {
        throw new \Exception('The number of arguments in the string does not match the number of arguments in a template.');
    } else {
        return $countArgs > 1 ? vsprintf($format, $args) : sprintf($format, reset($args));
    }
}

我认为这很容易,因为如果出现错误,它会返回错误的值。 您可以这样检查:

if (vsprintf($string, $wrongArray) === false) {
    // vsprintf has wrong number of arguments
}

但是如果函数类似于
vsprintf(format,args)
format='%3$s'
?@lmojzis:使用我提供的正则表达式
$format
?好的,让我解释一下。你的
args
array('a','b')
,而
格式是
'%3$s'
,那么显然你想得到
args
的第三个键,但是你的
计数(args)
int(2)
,但是它是通过的,因为匹配的数量是
int(1)
(int(1)@lmojzis:啊,是的……我不认为单用正则表达式就不能做到这一点,但是如果你找到了解决方案,请告诉我。但是,你可以搜索参数中的最大值,不是吗?你能补充更多的解释吗?@Shawn是的,我添加了一条注释。我相信
vsprintf()
允许
%%
表示单个
%%
?我认为这个正则表达式不允许这样做
public static function format($format, array $args)
{
    $pattern = "~%(?:(\d+)[$])?[-+]?(?:[ 0]|['].)?(?:[-]?\d+)?(?:[.]\d+)?[%bcdeEufFgGosxX]~";

    $countArgs = count($args);
    preg_match_all($pattern, $format, $expected);
    $countVariables = isset($expected[0]) ? count($expected[0]) : 0;

    if ($countArgs !== $countVariables) {
        throw new \Exception('The number of arguments in the string does not match the number of arguments in a template.');
    } else {
        return $countArgs > 1 ? vsprintf($format, $args) : sprintf($format, reset($args));
    }
}
if (vsprintf($string, $wrongArray) === false) {
    // vsprintf has wrong number of arguments
}