需要正则表达式来匹配不同格式的名称/值对

时间:2011-02-02 17:11:19

标签: php regex preg-match

我通过PHP Curl提取ASP / VBScript配置文件来进行一些文件处理并希望返回一些值。

字符串看起来像这样:

config1 = ""  
config2 = "VALUE:1:0:9" 'strange value comment 
otherconfig = False 
yetanotherconfig = False 'some comment

基本上,它的名称值对由等号分隔,值可选地包含在引号中,后面可选择注释。

我想在一个匹配组中返回实际的VALUE(False,VALUE:1:0:9等),而不管字符串的格式如何。

这是我到目前为止传递给preg_match的模式:

$pattern = '/\s*'.$configname.'\s*\=\s*(\".*?\"|.*?\r)/'

$ configname是我正在寻找的特定配置的名称,因此我将其传递给变量。

我仍然将括号包含在值中(而不是值本身),并且我也会返回带有值的注释。

感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

如果由于双引号替代而难以在一个匹配组中返回匹配值。返回参考可以提供帮助:

$pattern = '/\s*'.$configname.'\s*=\s*("?)(?<value>.*?)\1\s*[\'$]/'

应该做的伎俩。然后使用$result['value']

用英语解释:

  • 我跳过空格标识符=空格(简单)
  • 可以匹配引用为\ 1(第一个捕获括号)
  • "
  • 匹配任何不贪婪地引用为value
  • 的字符
  • 匹配\ 1(如果之前有一个",那么如果没有则为'
  • 可能会匹配某些空格
  • 必须与首发评论$pattern = '/\s*'.$configname.'\s*=\s*(?:"(.*?)"|(.*?)\s*[\'$])/' 或行尾
  • 相匹配

没有后退参考:

$result[1]

效率更高,但价值在$result[2]\

了解你的错误:

  • 您只需要.来保护字符串引用本身(这里是简单的引用)或者避免将preg保留字符解释为(^$,{{1} } ...)
  • 行尾标记为$,而不是\ r或\ n
  • 你从未避开评论

答案 1 :(得分:0)

\ r \ n将匹配CR字符(回车)。 你基本上是说我要匹配“???????”或者???????? [回车]

当然你会得到撇号,你已经匹配了它。 你必须把这些东西剥掉。

patter ='/\\*'。$ configname.'\s*\=\s*(\")(.*?)(?(1)\"|)\s*/'

答案 2 :(得分:0)

这个会起作用:

$pattern = '/
    \s*
    # name
    (?P<name>.*?)
    # =
    \s*=\s*
    # value
    (?P<val>
        "(?P<quoted>([^"]|\\\\"|\\\\\\\\)*)"
        |(?P<raw>.*?)
    )
    # comment
    \s*(?P<comment>\'.*)?
$/xm';

这将匹配输入字符串中的每个key = value对,而不是仅匹配特定的一对。

正则表达式会引用引号中的引号和转义引号(\")(例如"foo\"bar")。

将它与这样的函数一起使用:

function parse_config($string) {
    $pattern = '/
        \s*
        # name
        (?P<name>.*?)
        # =
        \s*=\s*
        # value
        (?P<val>
            "(?P<quoted>([^"]|\\\\"|\\\\\\\\)*)"
            |(?P<raw>.*?)
        )
        # comment
        \s*(?P<comment>\'.*)?
    $/xm';

    preg_match_all($pattern, $string, $matches, PREG_SET_ORDER);

    $config = array();
    foreach($matches as $match) {
        $name = $match['name'];
        if (!empty($match['quoted'])) {
            $value = str_replace(array('\\"','\\\\'), array('"','\\'), $match['quoted']);
        } else if (isset($match['raw'])) {
            $value = $match['raw'];
        } else {
            $value = '';
        }
        $config[$name] = $value;
    }

    return $config;
}

示例:

$string = "a = b\n
c=\"d\\\"e\\\\fgh\" ' comment";

$config = parse_config($string);

// output:

array('a' => 'b', 'c' => 'd"e\fgh');

其他例子:

$string = <<<EOF
config1 = ""
config2 = "VALUE:1:0:9" 'strange value comment
otherconfig = False
yetanotherconfig = False 'some comment
EOF;

print_r(parse_config($string));

// output:

Array
(
    [config1] => 
    [config2] => VALUE:1:0:9
    [otherconfig] => False
    [yetanotherconfig] => False
)