2013-04-28 107 views
3

我見過很多(你去檢舉此爲重複之前)就如何做到這一點,但由於某種原因,我的輸出是不工作:分割字符串與多個分隔符

// $delimiters wanted: ', ' | '; ' | ',' | ';' | ' , ' | ', and ' | ' and ' | ',and ' 
$str = 'Name 1, Name 2; Name 3;Name4 , Name 5,Name 6, and Name 7,and Name 8 and Name 9'; 
$delimiter = array(
    ', ', 
    '; ', 
    ';', 
    ',', 
    ' , ', 
    ', and ', 
    ' and ', 
    ',and ' 
); 
$str_new = explode($delimiter[0], str_replace($delimiter, $delimiter[0], $str)); 

然而,當我輸出陣列,我得到這個:

<?php foreach($str_new as $new) { echo 'a' . $new; } ?> 

Array (
    [0] => Name 1 
    [1] => Name 2 
    [2] => Name 3 
    [3] =>  // WHY IS THIS EMPTY? 
    [4] => Name 4 
    ... 
) 

那麼有沒有更好的方法來匹配我列出的分隔符​​?

+0

空間是在錯誤的地方按name4!你可以改名爲4而不是名字4 – caramba 2013-04-28 08:42:05

+0

@caramba我想表明,也有情況下逗號前後有空格。 – Ahhhhhhhhhhhhhdfgbv 2013-04-28 08:51:22

回答

5

我會使用正則表達式這樣你的情況:

preg_split('/,? ?and | ?[,;] ?/', $str) 

您也可能希望通過\s更換空間,如果其他空格字符可能會出現(比如TAB)或者甚至是\s*而不是?來覆蓋多個空間的情況。

+0

這個工程!與「爆炸」相比,它有多密集?看到影響會花費超過100分鐘嗎?我真的只有20以下的字符串。 – Ahhhhhhhhhhhhhdfgbv 2013-04-28 08:57:07

+0

@Ahhhhhhhhhhhhhdfgbv我不知道確切的值,但使用正則表達式的函數通常比簡單的字符串慢。所以,在大多數情況下'explode'應該比'preg_split'更快(我感覺,大約5次)。但是在我們的例子中'explode'方法被內部替換('preg_replace'或'str_replace')放慢了。 – Alexey 2013-04-28 09:02:24

+0

看起來像3個其他upvotes相比,其他。它也起作用,並在一行中。另外你甚至用TAB超越了。 – Ahhhhhhhhhhhhhdfgbv 2013-04-28 09:05:47

0

你從php.net嘗試過這樣的事情嗎?

<?php 

//$delimiters has to be array 
//$string has to be array 

function multiexplode ($delimiters,$string) { 

    $ready = str_replace($delimiters, $delimiters[0], $string); 
    $launch = explode($delimiters[0], $ready); 
    return $launch; 
} 

$text = "here is a sample: this text, and this will be exploded. this also | this one too :)"; 
$exploded = multiexplode(array(",",".","|",":"),$text); 

print_r($exploded); 
?> 

或者類似的東西Split String by Multiple Delimiters in PHP

+0

我試過這個,但是加入'',和''和'「和」'似乎填滿了東西。 – Ahhhhhhhhhhhhhdfgbv 2013-04-28 08:52:07

0

在您的代碼中,在Name 6, and Name 7之間,首先取代,,然後取代and

因此你結束了該字符串:

名稱1,名稱2,名稱3,NAME4,名稱5,名稱6日,名稱7,名稱8,名稱9

因此,空值...

輸出前,清潔你的結果數組,你應該罰款:

$str_out = array_filter($str_new); 
0

你的方法存在的問題是,你想用錯誤的方法解決問題。即使您設法創建分隔符列表,如果您需要例如用另一個字符分隔單詞,比方說,'$'符號?

您應該實現一個tokenizer/lexer,它可以通過char讀取輸入字符並區分空白,終端和非終端符號/字符。詞法分析器然後將生成一系列令牌,例如,

STRING-SYMBOL:'NAME1' 
KOMMA-SYMBOL 
AND-SYMBOL 
STRING-SYMBOL:'NAME2' 
SEMICOLON-SYMBOL 
STRING-SYMBOL:'NAME3' 
AND-SYMBOL 
... 
EOF-SYMBOL 

然後,您只需過濾掉任何非STRING-SYMBOL符號(或您結合使用AND-SYMBOL這是(恕我直言)唯一的岩石固溶串也是非常易於擴展和概括:一旦你擁有寫一個很好的標記器/詞法分析器,你可以用這種方法處理幾乎所有的字符串分析問題

寫一個標記器通常很簡單:它通過char掃描輸入字符並首先對字符進行分類它實現了一個簡單的狀態機收集將形成符號的字符。

您可能會Ÿ嘗試使用正則表達式來實現這一點,這也應該是可能的。無論如何,分詞器將生成一個令牌列表(或者根據請求檢索下一個)。它將檢索的最後一個令牌是EOF-TOKEN,表示輸入序列已完全遍歷。