2014-06-15 37 views
2

介紹

在PHP中,我將如何分割線與此語法:在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'" 
} 

更詳細的解釋

現在我不是最好的是解釋,所以我希望上面的例子說明了我的情況不夠好,你不會需要我的解釋,但在這裏它是無論如何:

我想每一個空間,除了對一些特定的拆分此字符串:

  • 如果空間尖括號或方括號它應該 不分割那條線。見編號2和3.
  • 支架內可能有一個支架。這應該是 只是作爲一個整個字符串返回。請參閱編號4.
  • 可能有不包含在括號內的項目。見編號1.
  • 未包裹在括號內的項目不會包含空格,除非撇號引用。見 5號
  • 的項目可以包含所有UTF-8字符[]除外<>

來源,可以幫助可能

Explode string except where surrounded by parentheses?


預先感謝您! 我知道這是一項艱鉅的任務,但我絕對不知道如何自己做這件事。

+0

'使preg_split()'? –

+0

只需要學習如何在這種情況下使用正則表達式,沒有什麼更多。這裏有一些鏈接[有關前瞻和lookbeheads的非常有用的信息](http://www.regular-expressions.info/lookaround.html) – Ohgodwhy

+0

@EugenRieck我在這裏讀過'preg_split()'不知道如果有東西在引號中。 – miestasmia

回答

5

與所有有關使用正則表達式來解析HTML免責聲明......只有當你準備好了一些遞歸美容 ...

匹配你想要的東西與拆分於你別t想要

如果你打算使用正則表達式,在這種情況下,爲了獲得你的數組,匹配你想要的將比分裂你不想要的更容易。這是一個起點,我們可以提煉:

(\[(?:[^[\]]++|(?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正則表達式重構技術。爲了使正則表達式易於理解,他將其分解成更小的命名模式: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)|(?&quotes) 
    ) 
) 

(?&skippable)(*SKIP)(*FAIL) 
| 
[ ]+ 
+0

@Downvoter,謹慎地解釋這個工作流程的downvote? – zx81

+0

@Locercus'爲什麼preg_split不能工作?'有時候,分割更容易匹配,有時匹配更容易分割。他們是兩種看待同一事物的方式。想象一下這個序列:白色,黑色,白色,黑色......你想要所有的白人。你可以分裂成黑色,或者匹配白人。 – zx81

+0

我沒有downvote,但這個人不需要一個解析器而不是一個正則表達式? –

3

更新:
這種模式也爲我工作
(\[(?:[^\[\]]*?|(?R))*\])|(<.*?>)|\G\s([^<>\[\]]+)
Demo

+0

感謝您添加[demo](http://regex101.com/r/sY5aB5)。 '[sadasd] ['不平衡,我誤解了什麼? – zx81

+0

你是對的,更新我的模式,有遞歸的問題,現在工作。 –

+0

'asqwedasd'仍然有一個額外的空間,但不錯的工作:) +1 – zx81

相關問題