解析字符串中的字符串?(Parsing a string within a string?)

2019-10-16 18:13发布

我有接受字符串参数例如功能:“VAR1 = VAL1 VAR2 = val2的VAR3 =‘一个瓦尔斯的列表’”;

我需要解析此字符串,并挑选出了var / VAL组合的。 这是很容易做到,直到引入类似VAR3 =“丘壑的名单”。 很明显,我不能使用爆炸,其中有我的样卡空格分隔字符串到一个数组。 我想创建此字符串正确地分配了var / VAL对的数组,我怎么能做到这一点的情况下,我有这样的事情VAR3?

Answer 1:

如果字符串的格式在石头设置 ,你可以这样做:

$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);

编辑:

更强大的功能,处理在所列出的值的转义字符:

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);


Answer 2:

这就是为什么传统的查询字符串使用&作为分隔符,而不是空格。

如果你能做到这一点,那么就使用parse_str获取数据了。

如果没有,你需要做的正则表达式:

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


Answer 3:

您可以使用正则表达式来查找所有匹配的VAR = val对的形式,如

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

那么你可以使用preg_match_all从那里解析它们,如果第二组的字符串以'字符,你可以解析清单开始。



Answer 4:

没有给整个事情想那么多,但怎么样呢? 也许对于这样一个小任务有点太多代码:)

<?php
  function parse_vars($string)
  {
    $exploded = explode(" ", $string);
    $return = array();
    foreach($exploded AS $entry){
      if(strpos($entry, "=") === false){      
        $return[$current] .= " ".$entry;
      }else{
        list($key, $value) = explode("=", $entry);
        $return[$key] = $value;
        $current = $key;
      }
    }   
    return $return;
  }

  $string = "var1=val1 var2=val2 var3='a list of vals'";
  print_r(parse_vars($string));
  die();
?>

顺便说我还是喜欢用正则表达式的解决方案"(\S*)=('.*?'|\S*)" ...



Answer 5:

也许你想在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

?>

这似乎做你寻找什么。



Answer 6:

恐怕这个问题不能用简单的正则表达式或通过简单的拆分来解决。 看一看在str_getcsv()在PHP 5.3功能。 我想你可以把它做你想要什么。

array str_getcsv  ( string $input  [, string $delimiter  [, string $enclosure  [, string $escape  ]]] )

您可以指定分隔符为空间而不是逗号和外壳为单引号,而不是双引号。 如果你能,挖掘这一功能的实现,理解它,并从中吸取教训。 否则,让PHP 5.3中使用它。

编辑:有,如果你不具备PHP 5.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;
    }
}

信用: http://www.electrictoolbox.com/php-str-getcsv-function/

编辑:这是在Perl的实现: 文字:: CSV 。 您可以下载源代码,看到的算法。 如果你是为它:)



Answer 7:

使用表达式与preg_split()

我不是伟大的RE,但我敢肯定,你可以用它来防止拆分单引号内的字符串。



Answer 8:

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

1)更换包含引号内有唯一的ID的所有字符串,并且ID存储在数组中。

所以

VAR1 = VAL1 VAR2 = val2的VAR3 = '的瓦尔斯列表'

VAR1 = VAL1 VAR2 = val2的VAR3 = asifab

阵列(“asifab”>“瓦尔斯的列表”)

2)由空间分割

阵列( “VAR1 = VAL1”, “VAR2 = val2的”, “VAR3 = asifab”)

阵列(“asifab”>“瓦尔斯的列表”)

3)等号分割

阵列( “VAR1”=> “VAL1”, “VAR2”=> “val2的”, “VAR3”=> “asifab”)

阵列(“asifab”>“瓦尔斯的列表”)

4)对于每个值,看它是否是你的阵列中,如果是,用空格分开的阵列值,并用其作为价值

阵列( “VAR1”=> “VAL1”, “VAR2”=> “val2的”, “的”, “值”, “VAR3”=>阵列( “一”, “列表”,))



文章来源: Parsing a string within a string?