【问题标题】:Preg_split on quote, except when followed by another quotePreg_split 在报价上,除非后面跟着另一个报价
【发布时间】:2013-08-12 23:48:33
【问题描述】:

我正在尝试使用分隔符捕获在引号字符 (") 上拆分 UTF-8 字符串,除非该引号后跟第二个引号 (""),以便(例如)

"A ""B"" C" & "D ""E"" F"

将分成三个元素

"A ""B"" C"
&
"D ""E"" F"

我一直在尝试使用:

$string = '"A ""B"" C" & "D ""E"" F"';
$temp = preg_split(
    '/"[^"]/mui',
    $string,
    null, 
    PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE
);

但没有成功,因为它给了我

array(7) {
  [0]=>
  string(2) " ""
  [1]=>
  string(1) """
  [2]=>
  string(1) "C"
  [3]=>
  string(2) "& "
  [4]=>
  string(2) " ""
  [5]=>
  string(1) """
  [6]=>
  string(2) "F""
}

所以它会丢失紧跟在引号后面的任何字符,除非该字符也是引号

在这个例子中,字符串中的第一个和最后一个字符都有一个引号,尽管情况可能并不总是这样,例如

{ "A ""B"" C" & "D ""E"" F" }

需要拆分成五个元素

{
"A ""B"" C"
&
"D ""E"" F"
}

谁能帮我搞定这个工作?

【问题讨论】:

  • 如果你拆分引号而不是另一个引号(假设没有消耗引号),你会得到{ "A ""B"" C" & "D ""E"" F" } .我认为这不是确定拆分位置的正确方法...您还有更多示例吗?
  • 如果拆分正确,我可以忍受消耗的开始/结束引号,因为引用的字符串可以识别为结果数组中的交替条目
  • 当有许多答案可以满足我的需要时,尤其是当一个似乎快一点,但使用的内存要多一点的时候,这会很棘手;而另一个速度稍慢,但使用的内存却很少 - 在我接受答案之前将使用更复杂的字符串运行一些更广泛的测试....但是谢谢大家,一如既往,你来救我了
  • @MarkBaker:我不知道情况如何,但还有几点需要注意:我的不适用于不匹配的引号,而 Jerry 的不适用于前导或尾随转义。假设前者占用更多内存,而后者占用更多时间,您可以通过使用(?:[^"]|"") 而不是([^"]|"") 来减少内存,并通过删除可选空格来减少执行时间。
  • @HamZa:我不知道。那是什么? It doesn’t work any better.

标签: php regex preg-split


【解决方案1】:

既然你说你不介意在拆分时使用引号,你可以使用表达式:

(?<!")\s?"\s?(?!")

其中使用了两个否定的环视。您的样本输出将是:

{ 
A ""B"" C
&
D ""E"" F
}

[我把\s? 用来消耗任何尾随空格,如果你想保留它们,请将它们删除]

【讨论】:

    【解决方案2】:

    我认为使用preg_match_all 可能会更容易:

    preg_match_all('/"([^"]|"")+"|[^"]+/', $string, $matches);
    

    Here’s a demo. 正则表达式匹配带引号的字符串或不匹配带引号的字符串,所以如果最后一部分没有右引号,它将忽略它;这可能需要更改,具体取决于您的情况。

    【讨论】:

    • 该死,我最好看看那个“新答案”通知,发布了同样的内容;)
    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    相关资源
    最近更新 更多