在sscanf()中使用时,%s在遇到%s后面的符号时不会停止匹配[重复]

问题描述 投票:0回答:4

我尝试使用

sscanf()
:

用 php 解析字符串
$n = sscanf($line, "%s.%s.%s=%s", $ws, $layer, $perm, $role);
echo $ws." - ".$layer." - ".$perm." - ".$role."\n";

并获得输出:

*.*.r=* -  -  -
topp.*.a=jdbs_watcher -  -  -

输入示例:

 *.*.r=*
 topp.*.a=jdbs_watcher

我期望看到第二个字符串:

topp - * - a - jdbc_watcher

为什么整个字符串被放入

$ws
变量中?

php scanf greedy
4个回答
3
投票

使用

^
避免太贪心:

<?php
$line = 'topp.*.a=jdbs_watcher';
$n = sscanf($line, "%[^.].%[^.].%[^=]=%s", $ws, $layer, $perm, $role);
echo $ws." - ".$layer." - ".$perm." - ".$role."\n";

3
投票

%s
将匹配空格分隔符之前尽可能多的字符。你可以使用 preg_match 得到类似的东西:

preg_match("/(.*)\.(.*)\.(.*)=(.*)/", $line, $matches);
array_shift($matches);
list($ws, $layer, $perm, $role) = $matches;

演示


2
投票

sscanf()
不是字符串解析器。它是一个格式化输入扫描器,用于使用 C 风格语法将格式化输入分配给变量。你想要完成的事情都可以用
explode()
来完成。

//Scan input
$n = sscanf($line, "%s", $input);

//Parse by .
$parsed = explode(".", $input);
//Parse by =
$parsed[2] = explode("=", $parsed[2]);

//Create bindings
$ws = $parsed[0];
$layer = $parsed[1];
$perm = $parsed[2][0];
$role = $parsed[2][1];

//Echo
echo $ws." - ".$layer." - ".$perm." - ".$role."\n";

2
投票

嗯,之前在 php.net 上发现了这种行为。

作为解决方法,您可以使用以下方法:

<?php
header('Content-Type: text/plain; charset=utf-8');

$line = 'topp.*.a=jdbs_watcher';

list($ws, $layer, $perm) = explode('.', $line);
list($perm, $role) = explode('=', $perm); 

echo $ws." - ".$layer." - ".$perm." - ".$role."\n";
?>

结果:

topp - * - a - jdbs_watcher
© www.soinside.com 2019 - 2024. All rights reserved.