【问题标题】:Parse a list of attribute/values in PHP解析 PHP 中的属性/值列表
【发布时间】:2010-12-09 00:03:18
【问题描述】:

给定一个带有属性/值对的字符串,例如

attr1="some text" attr2 = "some other text" attr3= "some weird !@'#$\"=+ text"

目标是解析它并输出一个关联数组,在这种情况下:

array('attr1' => 'some text',
      'attr2' => 'some other text',
      'attr3' => 'some weird !@\'#$\"=+ text')

注意等号前后不一致的间距、输入中的转义双引号和输出中的转义单引号。

【问题讨论】:

  • 你不是在解析标记语言,对吧?
  • 很好问!不,只是编写我自己的语法以便在命令行上轻松键入。
  • “便于在命令行输入”,那么你可能对docs.php.net/getopt感兴趣

标签: php regex parsing


【解决方案1】:

试试这样的:

$text = "attr1=\"some text\" attr2 = \"some other text\" attr3= \"some weird !@'#$\\\"=+ text\"";
echo $text;
preg_match_all('/(\S+)\s*=\s*"((?:\\\\.|[^\\"])*)"/', $text, $matches, PREG_SET_ORDER);
print_r($matches);

产生:

attr1="some text" attr2 = "some other text" attr3= "some weird !@'#$\"=+ text"

Array
(
    [0] => Array
        (
            [0] => attr1="some text"
            [1] => attr1
            [2] => some text
        )

    [1] => Array
        (
            [0] => attr2 = "some other text"
            [1] => attr2
            [2] => some other text
        )

    [2] => Array
        (
            [0] => attr3= "some weird !@'#$\"=+ text"
            [1] => attr3
            [2] => some weird !@'#$\"=+ text
        )

)

还有一个简短的解释:

(\S+)               // match one or more characters other than white space characters
                    // > and store it in group 1
\s*=\s*             // match a '=' surrounded by zero or more white space characters 
"                   // match a double quote
(                   // open group 2
  (?:\\\\.|[^\\"])* //   match zero or more sub strings that are either a backslash
                    //   > followed by any character, or any character other than a
                    //   > backslash
)                   // close group 2
"                   // match a double quote

【讨论】:

  • 第三个例子呢?
  • 是的,我忘了双重转义反斜杠(并仔细检查输出)。恐怕我有时对自己太自信了。谢谢。
  • php 和 actionscript(即 ecmascript/js btw)处理正则表达式的方式有什么区别吗?因为这个正则表达式只给出了 actionscript 中的前两个属性。
  • 在 ECMA-ish 正则表达式方面几乎没有经验,但您可能想尝试var regex = /(\S+)\s*=\s*"((?:\\.|[^\\"])*)"/g;,甚至var regex = /(\S+)\s*=\s*"((?:\\.|[^\"])*)"/g;(未经测试!)。
  • 两者都适用于 OP 给出的所有三种情况,但不适用于尾随反斜杠:(
【解决方案2】:

编辑:如果值以 attr4="something\\" 之类的反斜杠结尾,则此正则表达式失败

我不懂 PHP,但由于正则表达式在任何语言中都基本相同,所以我在 ActionScript 中就是这样做的:

var text:String = "attr1=\"some text\" attr2 = \"some other text\" attr3= \"some weird !@'#$\\\"=+ text\"";

var regex:RegExp = /\s*(\w+)\s*=\s*(?:"(.*?)(?<!\\)")\s*/g;

var result:Object;
while(result = regex.exec(text))
    trace(result[1] + " is " + result[2]);

我得到了以下输出:

attr1 是一些文本
attr2 是其他一些文本
attr3 有点奇怪!@'#$\"=+ 文本

【讨论】:

  • 只是一个小问题:如果值本身包含反斜杠,例如 attr3 = "\\" (可能也需要转义),它不会在后面看到负面效果。当然,这可能永远不会发生,OP 没有提到这种极端情况。
  • 是的,你是对的。这不是挑剔 - 如果字符串以反斜杠结尾,显然这会失败 - 比如attr4="something\\"
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2011-06-04
相关资源
最近更新 更多