在PHP中,如何使用以下语法拆分行:
<As's\\as'dsd> asqwedasd <sa sdasd> [a sadasd] [<asdsad> [as ddsd]] 'asdsad assd'
进入这个?
array(5) {
[0]=>
string(14) "<As's\\as'dsd>"
[1]=>
string(9) "asqwedasd"
[2]=>
string(10) "<sa sdasd>"
[3]=>
string(10) "[a sadasd]"
[4]=>
string(20) "[<asdsad> [as ddsd]]"
[5]=>
string(13) "'asdsad assd'"
}
现在我不是最擅长解释的,所以我希望上面的例子能够很好地解释我的情况,以至于你不需要我的解释,但无论如何它仍然存在:
我希望除了一些特定的空格之外,每个空格都要分割这个字符串:
Explode string except where surrounded by parentheses?
先感谢您!
我知道这是一项艰巨的任务,但我完全不知道如何做到这一点。
答案 0 :(得分:5)
所有关于使用正则表达式来解析HTML的免责声明......并且只有当你准备好了一些递归之美 ...
匹配你想要的东西与你想要的东西分裂
如果你打算使用正则表达式,在这种情况下,要获得你的数组,匹配你想要的东西比分割你不想要的东西更容易。这是一个起点,我们可以改进:
(\[(?:[^[\]]++|(?1))*\])|<[^>]*>|'[^']*'|[!-~]+
请参阅demo。
工作原理:
|
(\[(?:[^[\]]++|(?1))*\])
以递归方式匹配所有[sets of [brackets]]
<[^>]*>
匹配`''[^']*'
匹配'complete quotes'
。如果需要,可以对其进行改进,以考虑潜在的转义引用\'
[!-~]+
匹配任何剩余的非空格可打印字符。这是一个猜测,基于输入中的单词asqwedasd
,也可以进行细化。例如,如果要为了验证目的而指定剩余字符串没有<>[]
个字符,则可以使用此字符(由@CasimiretHippolyte建议)\s*\K[^[<]+(?<!\s)
示例代码
请参阅this demo的此输出。数组$m[0]
包含您想要的“拆分”。
$regex = "%(\[(?:[^[\]]++|(?1))*\])|<[^>]*>|'[^']*'|[!-~]+%";
$string = "<As's\\as'dsd> asqwedasd <sa sdasd> [a sadasd] [<asdsad> [as ddsd]] 'asdsad assd'";
$count = preg_match_all($regex,$string,$m);
print_r($m[0]);
另一种解决方案
@HamZa想出了另一个我觉得很漂亮的解决方案。他不想自己发布,但很高兴我把它添加到这里完成。
它是如何工作的?我们的想法是匹配正确的空格字符,并将它们分开。关于"regex-matching a pattern unless..."的问题详细解释了这一基本原则。首先,以与我的正则表达式类似的方式(但有更多的检查和递归),他定义了我们想要匹配的所有组,并匹配它们。然后,如果这些组匹配,则使用(*SKIP)(*F)
使正则表达式失败,之后引擎将跳转到匹配的最后一个字符后面的字符串中的位置。在交替的另一边,他匹配我们将分割的空格字符,我们知道这些是正确的空格字符,因为它们与左边的表达不匹配。在此阶段,我们可以使用preg_split
。
进一步的改进是使用我所谓的HRRT
,它代表HamZa Regex Refactoring Technique。为了使正则表达式易于消化,他将其分解为较小的命名模式:singlequotes
,brackets
等等。这使他可以为所有这些组定义另一个名称skippable
。在定义之后,匹配开始。如果我们可以匹配skippable
模式,则正则表达式会失败并显示(*SKIP)(*F)
,并且引擎将跳转到字符串中的下一个位置。
这就是它的要点。
这是the demo。
(?(DEFINE)
(?P<signs>
<
(?:
[^<>]
|
(?&signs)
)*
>
)
(?P<brackets>
\[
(?:
[^][]
|
(?&brackets)
)*
\]
)
(?P<singlequotes>
(?<!\\)'(?:[^\\]|\\.)*?'
)
(?P<doublequotes>
(?<!\\)"(?:[^\\]|\\.)*?"
)
(?P<quotes>
(?&singlequotes)|(?&doublequotes)
)
(?P<skippable>
(?&brackets)|(?&signs)|(?"es)
)
)
(?&skippable)(*SKIP)(*FAIL)
|
[ ]+
答案 1 :(得分:3)
更新:
这种模式对我来说也很有用
(\[(?:[^\[\]]*?|(?R))*\])|(<.*?>)|\G\s([^<>\[\]]+)
Demo