2013-04-28 106 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,表示输入序列已完全遍历。