我有接受字符串参数例如功能:“VAR1 = VAL1 VAR2 = val2的VAR3 =‘一个瓦尔斯的列表’”;
我需要解析此字符串,并挑选出了var / VAL组合的。 这是很容易做到,直到引入类似VAR3 =“丘壑的名单”。 很明显,我不能使用爆炸,其中有我的样卡空格分隔字符串到一个数组。 我想创建此字符串正确地分配了var / VAL对的数组,我怎么能做到这一点的情况下,我有这样的事情VAR3?
我有接受字符串参数例如功能:“VAR1 = VAL1 VAR2 = val2的VAR3 =‘一个瓦尔斯的列表’”;
我需要解析此字符串,并挑选出了var / VAL组合的。 这是很容易做到,直到引入类似VAR3 =“丘壑的名单”。 很明显,我不能使用爆炸,其中有我的样卡空格分隔字符串到一个数组。 我想创建此字符串正确地分配了var / VAL对的数组,我怎么能做到这一点的情况下,我有这样的事情VAR3?
如果字符串的格式在石头设置 ,你可以这样做:
$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);
这就是为什么传统的查询字符串使用&作为分隔符,而不是空格。
如果你能做到这一点,那么就使用parse_str获取数据了。
如果没有,你需要做的正则表达式:
preg_match_all('/(\S*)=('.*?'|\S*)/g', $your_string, $matches);
print_r($matches);
您可以使用正则表达式来查找所有匹配的VAR = val对的形式,如
(\w[0-9A-Za-z]+)=(\'?\w([0-9A-Za-z ]|\\\'|\\=)+\'?)
那么你可以使用preg_match_all从那里解析它们,如果第二组的字符串以'字符,你可以解析清单开始。
没有给整个事情想那么多,但怎么样呢? 也许对于这样一个小任务有点太多代码:)
<?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*)"
...
也许你想在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
?>
这似乎做你寻找什么。
恐怕这个问题不能用简单的正则表达式或通过简单的拆分来解决。 看一看在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 。 您可以下载源代码,看到的算法。 如果你是为它:)
使用表达式与preg_split()
我不是伟大的RE,但我敢肯定,你可以用它来防止拆分单引号内的字符串。
好吧,你不能改变它。 我会用这样的算法:
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”=>阵列( “一”, “列表”,))