2011-12-22 78 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));