Php 在字符串中解析字符串?

Php 在字符串中解析字符串?,php,parsing,variables,string,Php,Parsing,Variables,String,我有一个接受字符串参数的函数,例如:“var1=val1 var2=val2 var3='a VAL列表' 我需要解析这个字符串并选择var/val组合。在引入var3='a vals列表'这样的东西之前,这是很容易的。显然,我不能使用空格分隔符将字符串分解成数组,这让我有点卡住了。我想从这个字符串创建一个数组,并正确分配var/val对,在我有var3这样的东西的情况下,我怎么做呢?好的,你不能更改它。我会使用这样的算法: 1)用唯一Id替换引号中包含的所有字符串,并将Id存储在数组中 所以

我有一个接受字符串参数的函数,例如:“var1=val1 var2=val2 var3='a VAL列表'


我需要解析这个字符串并选择var/val组合。在引入var3='a vals列表'这样的东西之前,这是很容易的。显然,我不能使用空格分隔符将字符串分解成数组,这让我有点卡住了。我想从这个字符串创建一个数组,并正确分配var/val对,在我有var3这样的东西的情况下,我怎么做呢?

好的,你不能更改它。我会使用这样的算法:

1)用唯一Id替换引号中包含的所有字符串,并将Id存储在数组中

所以

var1=val1 var2=val2 var3='a VAL列表'

变成

var1=val1 var2=val2 var3=asifab

数组(“asifab”=>“VAL列表”)

2)按空格分割

数组(“var1=val1”、“var2=val2”、“var3=asifab”)

数组(“asifab”=>“VAL列表”)

3)等号分割

数组(“var1”=>“val1”、“var2”=>“val2”、“var3”=>“asifab”)

数组(“asifab”=>“VAL列表”)

4)对于每个值,查看它是否在数组中,如果在数组中,则将数组值按空格分割,并将其用作值

数组(“var1”=>“val1”、“var2”=>“val2”、“var3”=>数组(“a”、“list”、“of”、“value”))


将正则表达式与
preg_split()
一起使用


我对RE不太在行,但我相信您可以使用它来防止在单引号内拆分字符串。

如果字符串的格式设置为固定格式,您可以执行以下操作:

$string = "var1=val1 var2=val2 var3='this is a test'";

$vars = array();
$i = 0;
while ($i < strlen($string)) {

    $eqIndex = strpos($string, "=", $i);
    $varName = substr($string, $i, $eqIndex - $i);

    $i = $eqIndex + 1;

    if ($string[$i] == "'") 
    {
        $varEndIndex = strpos($string, "'", ++$i);
    }
    else
    {
        $varEndIndex = strpos($string, " ", $i);
        if ($varEndIndex === FALSE) $varEndIndex = strlen($string);
    }

    $varValue = substr($string, $i, $varEndIndex - $i);

    $vars[$varName] = $varValue;

    $i = $varEndIndex + 1;
}

print_r($vars);
$string=“var1=val1 var2=val2 var3='这是一个测试';
$vars=array();
$i=0;
而($i
编辑:

处理引用值中转义字符的更健壮的函数:

function getVarNameEnd($string, $offset) {

    $len = strlen($string);
    $i = $offset;
    while ($i < $len) {

        if ($string[$i] == "=")
            return $i;
        $i++;
    }

    return $len;
}

function getValueEnd($string, $offset) {

    $len = strlen($string);
    $i = $offset;
    if ($string[$i] == "'") {
        $quotedValue = true;
        $i++;
    }
    while ($i < $len) {

        if ($string[$i] == "\\" && $quotedValue)
            $i++;
        else if ($string[$i] == "'" && $quotedValue)
            return $i + 1;
        else if ($string[$i] == " " && !$quotedValue)
            return $i;
        $i++;
    }

    return $len;
}

function getVars($string) {

    $i = 0;
    $len = strlen($string);
    $vars = array();
    while ($i < $len) {

        $varEndIndex = getVarNameEnd($string, $i);
        $name = substr($string, $i, $varEndIndex - $i);
        $i = $varEndIndex + 1;

        $valEndIndex = getValueEnd($string, $i);
        $value = substr($string, $i, $valEndIndex - $i);
        $i = $valEndIndex + 1;

        $vars[$name] = $value;
    }

    return $vars;
}

$v = getVars("var1=var1 var2='this is a test' var3='this has an escaped \' in it' var4=lastval");
print_r($v);
函数getVarNameEnd($string,$offset){ $len=strlen($string); $i=$offset; 而($i<$len){ 如果($string[$i]==“=”)) 返回$i; $i++; } 返回$len; } 函数getValueEnd($string,$offset){ $len=strlen($string); $i=$offset; 如果($string[$i]==“'”){ $quotedValue=true; $i++; } 而($i<$len){ 如果($string[$i]==“\\”&&$quotedValue) $i++; else if($string[$i]==“'”&&$quotedValue) 返回$i+1; else if($string[$i]==“”&&!$quotedValue) 返回$i; $i++; } 返回$len; } 函数getVars($string){ $i=0; $len=strlen($string); $vars=array(); 而($i<$len){ $varEndIndex=getVarNameEnd($string,$i); $name=substr($string,$i,$varEndIndex-$i); $i=$varEndIndex+1; $ValenIndex=getValueEnd($string,$i); $value=substr($string,$i,$valEndIndex-$i); $i=$ValenIndex+1; $vars[$name]=$value; } 返回$VAR; } $v=getVars(“var1=var1 var2='这是一个测试'var3='这其中有一个转义\'var4=lastval'); 印刷费($v);
这就是查询字符串使用&作为分隔符而不是空格的传统原因

如果你能做到这一点,那么就用它来获取数据

如果没有,则需要执行正则表达式:

preg_match_all('/(\S*)=('.*?'|\S*)/g', $your_string, $matches);
print_r($matches);

可以使用正则表达式查找所有匹配的var=val对,例如

(\w[0-9A-Za-z]+)=(\'?\w([0-9A-Za-z ]|\\\'|\\=)+\'?)

然后您可以使用从那里解析它们,如果第二组的字符串以“字符”开头,您可以解析列表。

恐怕这个问题不能用简单的正则表达式或简单的拆分来解决。看看PHP5.3中的函数。我想你可以让它完全按照你的意愿来做

array str_getcsv  ( string $input  [, string $delimiter  [, string $enclosure  [, string $escape  ]]] )
您可以将分隔符指定为空格而不是逗号,将附件指定为单引号而不是双引号。如果可以,深入了解该函数的实现,理解它,并从中学习。否则,请使用PHP5.3

编辑:如果您没有PHP5.3:

if(!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
        $fp = fopen("php://memory", 'r+');
        fputs($fp, $input);
        rewind($fp);
        $data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
        fclose($fp);
        return $data;
    }
}
学分:


编辑:以下是Perl中的实现:。您可以下载源代码并查看算法。如果你准备好了:)

没有仔细考虑整件事,但是这个呢?对于这样一个小任务,代码可能有点太多:)


也许您想要parse_str()函数

以下是PHP.net中的示例:

<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz

parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

?>


它似乎完全符合您的要求。

不幸的是,是的,我坚持在这个结构中工作。函数原型要求将var/vals列表作为单个字符串传递。但在本例中,$参数是一个字符串,因此我无法使用foreach()遍历它。当前版本不会使用空格解析值(\w不包括空格)。另外,作为值的一部分的转义单引号会发生什么情况?如果“=”是单引号中的值的一部分会怎样?如果使用查询字符串语法,则使用%字符转义单引号和等号。我为您提供的字符串类型添加了一个解决方案。这对于我给出的示例非常有效,现在尽我所能尝试“打破”它:P--谢谢。当值中有转义单引号时,此解决方案将不起作用。正在为您开发一个更好的功能该功能似乎确实完成了我需要做的事情,但我们尚未升级到5.3。。。然后找到它的定义,并复制它:)这是一个你可以很容易地用正则表达式做很多工作。您也可能没有运行该f所需的权限
<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz

parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

?>