2011-12-22 79 views
3

可能重复:
Split string by delimiter, but not if it is escaped分割字符串,但不包括一些字符

我已经产生了串形成被管|字符分隔IBM Informix数据库并有一些数据错误,这意味着在数据里面有反斜杠+管道。我想仅将这些字符串从管道符号分开,而不是从反斜杠+管道\|或其他符号与管道。

这是我的代码,但它仅适用于管道字符:

foreach(glob("ssbstat.unl") as $file) 
{ 
    $c=0;  
    if(($load = fopen($file, "r")) !== false) 
    { 
     $line = fgets($load);   
     $count= count(explode('|', $line)); 
     echo $fm= str_repeat('%[^|]|', $count)."%s\n";  

     do 
     { 
      echo $line; 
      print_r($line); 
      if($c++>10) break; 
     } while ($line = fscanf($load, $fm)); 
    } 
} 

谁能帮助我做到这一点?

+1

PHP4?时间升级... – 2011-12-22 13:33:09

+1

你需要排除哪些“其他字符”,你是什么意思“或其他符号与管道”?是你想忽略的唯一的东西? – 2011-12-22 13:38:07

回答

1

你可以用preg_split做到这一点。这件[^\\\\]指定用反斜杠管道应(四个反斜杠都需要适当转义被忽略,你可以添加你想要的[]内忽略任何其它字符。

print_r(preg_split('/(?<![\\\\])\|/', 'This\|is a|test|string')); 
+0

这不行!一个字符串,例如'This \ | is a | test | string''将会返回:'Array([0] =>“This \ | is”[1] =>“tes”[2] =>“string” )',因为你在'|'之前说任何字符都不是反斜杠,它也是分割函数的一部分,所以它不在。这就是为什么你应该在之前使用preg_replace(如我已回答) – noob 2011-12-22 13:57:27

+0

良好的捕获。我真的应该使用负面的后台。 'preg_replace'不是必需的。答案已更新。 – 2011-12-22 14:13:12

+0

+1非常好的解决方案! – noob 2011-12-22 14:25:51

-1

更换backslah + pipesign有一个占位符,然后通过pipesign爆炸,然后替换回去占位符backslah + pipesign

+0

你建议什么样的占位符?必须是不可能出现在数据中的东西,或者你的最后一个替换可能会破坏它。 – 2011-12-22 13:37:18

+0

你的字符串中不可能出现的任何东西,比如“{[%my_great_placeholder%]}”或者 – 2011-12-22 13:39:03

+0

我已经做了,但是有一个重新约100000行。这是如此的花时间。我想要一个简短的方法。这个正则表达式可以发展吗? – lankitha 2011-12-22 13:39:04

3

做这样的:

<?php 
$line = preg_replace("/([^\\\])\|/", "$1 |", "Hi \|error\| man|ok man|perfect man"); 
print_r(preg_split('/[^\\\]\|/', $line)); 

将输出:

Array ([0] => "Hi \|error\| man" [1] => "ok man" [2] => "perfect man") 

Testet!

编辑:像Maerlyn说,这也是可能的:

<?php 
$line = "Hi \|error\| man|ok man|perfect man"; 
print_r(preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $line));