PHP分割字符串,但将引号中的单词视为一个单词

4
我该如何拆分以下字符串:
"foo bar"ANDbar"foo"AND"foofoo" lorem "impsum"

进入

array('"foo bar"', 'ANDbar', '"foo"', 'AND',' "foofoo"', "lorem", '"impsum"')

我查看了这个答案:https://dev59.com/kHE95IYBdhLWcg3wrP-w#2202489 但在我的字符串中没有空格链接时无法使用。
$text = '"foo bar"ANDbar"foo"AND"foofoo" lorem "impsum"';
preg_match_all('/"(?:\\\\.|[^\\\\"])*"|\S+/', $text, $matches);
print_r($matches);

结果:

0 => array:7 [
 0 => ""foo bar""
    1 => "ANDbar"foo"AND"foofoo""
    2 => "lorem"
    3 => ""impsum""
  ]

但我需要这个:
0 => array:7 [
 0 => ""foo bar""
    1 => "ANDbar"
    2 => ""foo""
    3 => "AND"
    4 => ""foofoo""
    5 => "lorem"
    6 => ""impsum""
  ]

感谢您的选择:D
谢谢 :D

尝试使用 preg_match_all('~(?|"([^\\\\"]*(?:\\\\.[^"\\\\]*)*)"|([^\s"]+))~s', $s, $matches)。然后使用 print_r($matches[1]) 检查结果。如果您需要带引号的子字符串,则可以使用 preg_match_all('~"[^\\\\"]*(?:\\\\.[^"\\\\]*)*"|[^\s"]+~s', $s, $matches) 并使用 print_r($matches[0]) 获取它们。 - Wiktor Stribiżew
哪一个?1)还是2)? - Wiktor Stribiżew
两个都可以,但对于我的情况,第一个更好 ;) - Yannik
不需要在问题中添加“已解决”,因为您已将答案标记为解决方案,所以该问题已被SO标记为已回答。我撤销了那个编辑。 - Wiktor Stribiżew
3个回答

3
你可以使用:
if (preg_match_all('~(?|"([^\\\\"]*(?:\\\\.[^"\\\\]*)*)"|([^\s"]+))~s', $s, $matches)) 
{
    print_r($matches[1]);
}

请查看正则表达式演示

详细信息

  • (?| - 开始一个分支重置组:
    • " - 一个 " 字符
    • ([^\\\\"]*(?:\\\\.[^"\\\\]*)*) - 第1组:任意0个或多个非\"字符,后跟0个或多个转义字符和任意0个或多个非\"字符
    • " - 一个 " 字符
  • | - 或者
    • ([^\s"]+) - 第1组:一个或多个非空格和"的字符
  • ) - 分支重置组结束。

请查看PHP演示

$s = '"foo bar"ANDbar"foo"AND"foofoo" lorem "impsum"';
if (preg_match_all('~(?|"([^\\\\"]*(?:\\\\.[^"\\\\]*)*)"|([^\s"]+))~s', $s, $matches)) 
{
    print_r($matches[1]);
}
// => Array ( [0] => foo bar [1] => ANDbar [2] => foo [3] => AND [4] => foofoo [5] => lorem [6] => impsum )

0

您可以使用:

<?php

$orgstr = '"foo bar"ANDbar"foo"AND"foofoo" lorem "impsum"';
$org_arr = explode('"',$orgstr);

$chk = 0;
$new_arr = array();
foreach($org_arr as $k=>$val){
     if($val=='') continue;
     if($chk%2==0) array_push($new_arr,'""'.trim($val).'""'); else array_push($new_arr,'"'.trim($val).'"');
     $chk++;
}

echo "<br><pre>";
print_r($new_arr);
echo "</pre>";
?>

0

看起来你想要在引号处分割(忽略第一个和最后一个引号),然后在元素1、3、5...周围放置引号,并从元素2、4、6...中删除空格。如果是这样的话,你可以完全这样做:

$str = '"foo bar"ANDbar"foo"AND"foofoo" lorem "impsum"';
// ignore first/last quote:
$str = trim($str, '"');
// explode on quotes
$a = explode('"', $str);
foreach($a as $i=>$v) {
  // Place quotes around indexes 1, 3, 5...
  if($i%2 == 1) $a[$i] = '"'.$v.'"';
  // Trim whitespace around indexes 2, 4, 6...
  if($i%2 == 0) $a[$i] = trim($v);
}

你可以将这些函数结合起来以使其更简短,但是我想确保你能看到它确实做到了你所要求的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接