使用 = 和 & 解析字符串 作为分隔符,但不是全部 & 是向前看的分隔符

发布于 2024-07-18 08:30:53 字数 343 浏览 3 评论 0原文

我在 PHP 中有这个字符串:

$string = "name=Shake & Bake&difficulty=easy";

我想将其解析为数组:

Array
(
    [name] => Shake & Bake 
    [difficulty] => easy
) 

NOT:

Array
(
    [name] => Shake
    [difficulty] => easy
) 

最有效的方法是什么?

I have this string in PHP:

$string = "name=Shake & Bake&difficulty=easy";

For which I want to parse into array:

Array
(
    [name] => Shake & Bake 
    [difficulty] => easy
) 

NOT:

Array
(
    [name] => Shake
    [difficulty] => easy
) 

What is the most efficient way to do this ?

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

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

发布评论

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

评论(5

但可醉心 2024-07-25 08:30:54

可能有一种更有效的方法可以做到这一点,但请尝试

$foo = 'name=Shake & Bake&difficulty=easy';
$pairs = preg_split('{&(?=[^\s])}',$foo);
//$pairs = preg_split('/&(?=[^\s])/',$foo); //equivalent, using different delimiters.
//$pairs = preg_split('%&(?=[^\s])%',$foo); //equivalent, using different delimiters.
$done = Array();
foreach($pairs as $keyvalue){
    $parts = preg_split('{=}',$keyvalue);
    $done[$parts[0]] = $parts[1];
}
print_r($done); 

PHP 的正则表达式引擎 PCRE,它支持前瞻断言。 谷歌搜索 PCRE、PHP、RegEx、前瞻断言和零宽度断言应该会为您提供有关该主题的更多信息。

There's probably a more effective way of doing this, but try

$foo = 'name=Shake & Bake&difficulty=easy';
$pairs = preg_split('{&(?=[^\s])}',$foo);
//$pairs = preg_split('/&(?=[^\s])/',$foo); //equivalent, using different delimiters.
//$pairs = preg_split('%&(?=[^\s])%',$foo); //equivalent, using different delimiters.
$done = Array();
foreach($pairs as $keyvalue){
    $parts = preg_split('{=}',$keyvalue);
    $done[$parts[0]] = $parts[1];
}
print_r($done); 

PHP's regex engine is PCRE, and it supports look ahead assertions. Googling around for PCRE, PHP, RegEx, look ahead assertions and zero width assertions should give you more than you ever want to know on the subject.

一个人的旅程 2024-07-25 08:30:54

正则表达式似乎是做到这一点的最佳方法。

<html>
<head>
  <title>Test params</title>
</head>
<body>
<?php
test_build('a=b');
test_build('blah=foo&foo=foo2');
test_build('blah=foo&foo&foo2=foo3&foo');

function test_build($string) {
  echo "<p>Testing: $string</p>\n";
  $params = build_params($string);
  if ($params) {
    echo "<ul>\n";
    foreach ($params as $k => $v) {
      echo "<li>'$k' => '$v'</li>\n";
    }
    echo "</ul>\n";
  } else {
    echo "<p>Found no parameters.</p>\n";
  }
}

function build_params($string) {
  preg_match_all('!([^=&]+)=([^=]*)(?=(&|$))!', $string, $matches);
  $ret = array();
  for ($i=0; $i<sizeof($matches[1]); $i++) {
    $ret[$matches[1][$i]] = $matches[2][$i];
  }
  return $ret;
}
?>
</body>
</html>

输出:

Testing: a=b

    * 'a' => 'b'

Testing: blah=foo&foo=foo2

    * 'blah' => 'foo'
    * 'foo' => 'foo2'

Testing: blah=foo&foo&foo2=foo3&foo

    * 'blah' => 'foo&foo'
    * 'foo2' => 'foo3&foo'

Regular expressions seems to be the best way to do this.

<html>
<head>
  <title>Test params</title>
</head>
<body>
<?php
test_build('a=b');
test_build('blah=foo&foo=foo2');
test_build('blah=foo&foo&foo2=foo3&foo');

function test_build($string) {
  echo "<p>Testing: $string</p>\n";
  $params = build_params($string);
  if ($params) {
    echo "<ul>\n";
    foreach ($params as $k => $v) {
      echo "<li>'$k' => '$v'</li>\n";
    }
    echo "</ul>\n";
  } else {
    echo "<p>Found no parameters.</p>\n";
  }
}

function build_params($string) {
  preg_match_all('!([^=&]+)=([^=]*)(?=(&|$))!', $string, $matches);
  $ret = array();
  for ($i=0; $i<sizeof($matches[1]); $i++) {
    $ret[$matches[1][$i]] = $matches[2][$i];
  }
  return $ret;
}
?>
</body>
</html>

Output:

Testing: a=b

    * 'a' => 'b'

Testing: blah=foo&foo=foo2

    * 'blah' => 'foo'
    * 'foo' => 'foo2'

Testing: blah=foo&foo&foo2=foo3&foo

    * 'blah' => 'foo&foo'
    * 'foo2' => 'foo3&foo'
我的鱼塘能养鲲 2024-07-25 08:30:54
<?php
$pattern ='/([^&]+)=([^=]+)(?=$|&[^=]+=)/';
$test = array( 'name=Shake & Bake&difficulty=easy', 'name=Shake&Bake&difficulty=easy', 'difficulty=easy&name=Shake & Bake', 'difficulty=easy&name=Shake&Bake', 'name=Shake&Bake', 'difficulty=easy', 'name=Shake&Bake&foo&difficulty=easy', 'name=Shake&Bake&difficulty=easy&', 'name=Shake&Bake&difficulty=' ); foreach($test as $foo) { preg_match_all($pattern, $foo, $m); echo $foo, "\n"; for($i=0; $i<count($m[0]); $i++) { echo ' ', $m[1][$i], ' =$gt; "', $m[2][$i], "\"\n"; } echo "\n"; } ?>

produces

name=Shake & Bake&difficulty=easy
  name => "Shake & Bake"
  difficulty => "easy"
name=Shake&Bake&difficulty=easy name => "Shake&Bake" difficulty => "easy"
difficulty=easy&name=Shake & Bake difficulty => "easy" name => "Shake & Bake"
difficulty=easy&name=Shake&Bake difficulty => "easy" name => "Shake&Bake"
name=Shake&Bake name => "Shake&Bake"
difficulty=easy difficulty => "easy"
name=Shake&Bake&foo&difficulty=easy name => "Shake&Bake&foo" difficulty => "easy"
name=Shake&Bake&difficulty=easy& name => "Shake&Bake" difficulty => "easy&"
name=Shake&Bake&difficulty= name => "Shake&Bake"

which seems to be working (except for difficulty= not being matched in the last example).
I'm not sure whether a once-only subpattern matching would improve the speed. You might want to look this up.

<?php
$pattern ='/([^&]+)=([^=]+)(?=$|&[^=]+=)/';
$test = array( 'name=Shake & Bake&difficulty=easy', 'name=Shake&Bake&difficulty=easy', 'difficulty=easy&name=Shake & Bake', 'difficulty=easy&name=Shake&Bake', 'name=Shake&Bake', 'difficulty=easy', 'name=Shake&Bake&foo&difficulty=easy', 'name=Shake&Bake&difficulty=easy&', 'name=Shake&Bake&difficulty=' ); foreach($test as $foo) { preg_match_all($pattern, $foo, $m); echo $foo, "\n"; for($i=0; $i<count($m[0]); $i++) { echo ' ', $m[1][$i], ' =$gt; "', $m[2][$i], "\"\n"; } echo "\n"; } ?>

produces

name=Shake & Bake&difficulty=easy
  name => "Shake & Bake"
  difficulty => "easy"
name=Shake&Bake&difficulty=easy name => "Shake&Bake" difficulty => "easy"
difficulty=easy&name=Shake & Bake difficulty => "easy" name => "Shake & Bake"
difficulty=easy&name=Shake&Bake difficulty => "easy" name => "Shake&Bake"
name=Shake&Bake name => "Shake&Bake"
difficulty=easy difficulty => "easy"
name=Shake&Bake&foo&difficulty=easy name => "Shake&Bake&foo" difficulty => "easy"
name=Shake&Bake&difficulty=easy& name => "Shake&Bake" difficulty => "easy&"
name=Shake&Bake&difficulty= name => "Shake&Bake"

which seems to be working (except for difficulty= not being matched in the last example).
I'm not sure whether a once-only subpattern matching would improve the speed. You might want to look this up.

空城缀染半城烟沙 2024-07-25 08:30:54

函数 parse_str() 正是您所需要的 - 只是确保出于明显的安全原因传递第二个参数。 不过,您需要翻译您的输入字符串:

$string = "name=Shake & Bake&difficulty=easy";
parse_str(str_replace(' & ', '+%26+', $string), $array);

The function parse_str() does exactly what you need - just make sure, you pass the second parameter for obvious security reasons. You need to translate your input string, though:

$string = "name=Shake & Bake&difficulty=easy";
parse_str(str_replace(' & ', '+%26+', $string), $array);
×眷恋的温暖 2024-07-25 08:30:54

urlencode() & 在“摇动和烘烤”中并使用 parse_str()

urlencode() the & in "Shake & Bake" and use parse_str()

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