假设我在mikrotik路由器下面有这个脚本,我想提取一个带有键和值的数组,如果有另一个值包含一个=字符,
add name=100YER on-login=":do {:put \"a\";} on-error={};" rate-limit=256k/512k结果应该是这样:
$result=array ('name'=>'100YER', on-login=>':do {:put \"a\";} on-error={};', 'rate-limit'=>'256k/512k');我使用这个regex将其拆分为=,但问题在于登录时的值。
if (preg_match_all('/[^=]+/i', $response, $MATCHES) ){
//
}发布于 2020-10-04 18:24:12
您可以使用两个包含分支重置组的捕获组:
(\w+(?:-\w+)*)=(?|"((?:[^"]+|(?<=\\)")++)"|([^"\s]+))解释
( Capture group 1 \w+(?:-\w+)*可选地匹配1+单词字符,然后是-和1+单词字符)闭组1=匹配(?|分支复位组"(匹配"并启动组2 (?:[^"]+|(?<=\\)")++匹配除"或\"以外的任何字符- `)"` Close group 2 and match `"`
- `|` Or
- `([^"\s]+)` Capture **group 3**, match any char except `"` or a whitespace char)闭分支复位组例如
$re = '/(\w+(?:-\w+)*)=(?|"((?:[^"]+|(?<=\\\\)")++)"|([^"\s]+))/';
$str = 'add name=100YER on-login=":do {:put \\"a\\";} on-error={};" rate-limit=256k/512k';
preg_match_all($re, $str, $matches);
$result = array_combine($matches[1], $matches[2]);
print_r($result);输出
Array
(
[name] => 100YER
[on-login] => :do {:put \"a\";} on-error={};
[rate-limit] => 256k/512k
)发布于 2020-10-04 20:53:35
要改进@Thefourthbird的模式,请使用PHP:忽略引号中转义引号的Regex“最佳”技术中的智慧。这不仅提高了模式效率的步骤计数,它还更准确地区分反斜杠是字面上使用的和用于转义的。
否则,我完全同意分支重置最适合于将目标子字符串保持在preg_match_all()输出数组的一致列中。
代码:(演示)
$string = <<<MIKROTIK
add name=100YER on-login=":do {:put \"a\";} on-error={};" rate-limit=256k/512k
MIKROTIK;
var_export(
preg_match_all(
'~(\w+(?:-\w+)*)=(?|"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|([^" ]+))~',
$string,
$out
)
? array_combine($out[1], $out[2])
: []
);输出:
array (
'name' => '100YER',
'on-login' => ':do {:put \\"a\\";} on-error={};',
'rate-limit' => '256k/512k',
)https://stackoverflow.com/questions/64198123
复制相似问题