2013-07-02 72 views
3

現在我已經有了非常基本的正則表達式技能,只用了幾次正則表達式來處理基本的東西。之前可能已經提出過這個問題,我很抱歉,但是我找不到任何答案。發現類似,雖然並試圖適應它,但無濟於事。 好的,對於這個問題 - 如何僅替換特定字符之間的空間(本例中是雙引號)?用php正則表達式替換部分字符串

說我有以下字符串:

「使命播客」 modcast ABC 「DEF」

我想更換使命播客之間的空間,以及作爲dē & 之間那些˚F而離開其他部分未觸及。

P.S.如果空間是一個字符串呢?一個例子也是受歡迎的。

編輯這一點我希望現在它更清楚。 編輯2:我需要在php中的字符串上執行此操作,並在shell中執行它。 編輯3:對不起,我改變了整個問題3次,這只是我自己很困惑。乾杯!

+1

那麼你到目前爲止嘗試過什麼? –

+0

你能提供更多的例子,而不是'find/vol_stor/8s8a912hj1 | grep「」mission \ | podcast「」| grep「modcast」'?至少2株將是多大的幫助 – Angga

+0

嗯,我還沒有嘗試任何事情,因爲我不知道如何保護範圍內匹配字符串的一部分,只有更換它們的括號內的字中有什麼。所以,我願意接受各種建議:) –

回答

2

說明

我會先分割字符串攻擊這個問題分成要麼引用或不帶引號的字符串組。

然後通過匹配進行迭代,如果填充了組1,則該字符串被引用,因此只需替換捕獲組0即可進行簡單替換。如果未填充捕獲組1,則跳至下一個匹配項。

在每一次迭代中,你都會想要建立一個新的字符串。

由於分割字符串是困難的部分,我會用這個表達式:

("[^"]*")|[^"]*

enter image description here

示例文字

"mission podcast" modcast A B C "D E F" 

代碼

PHP Code Example: 
<?php 
$sourcestring="your source string"; 
preg_match_all('/("[^"]*")|[^"]*/i',$sourcestring,$matches); 
echo "<pre>".print_r($matches,true); 
?> 

捕捉組

$matches Array: 
(
    [0] => Array 
     (
      [0] => "mission podcast" 
      [1] => modcast A B C 
      [2] => "D E F" 
      [3] => 
     ) 

    [1] => Array 
     (
      [0] => "mission podcast" 
      [1] => 
      [2] => "D E F" 
      [3] => 
     ) 

) 

PHP實例

這PHP腳本將只替換引號中的字符串內的空間。

工作例如:http://ideone.com/jBytL3

代碼

<?php 

$text ='"mission podcast" modcast A B C "D E F"'; 

preg_match_all('/("[^"]*")|[^"]*/',$text,$matches); 

foreach($matches[0] as $entry){ 
    echo preg_replace('/\s(?=.*?")/ims','~~new~~',$entry); 
    } 

輸出

"mission~~new~~podcast" modcast A B C "D~~new~~E~~new~~F" 
+0

感謝你非常希望得到答案,並花時間來說明它!因爲它會做的完美,我希望我可以避免分裂成陣列。你有任何建議,而不是** preg_replace **而不是? –

+0

查看更新的答案哪個包括一個php和正則表達式的解決方案。 –

+0

其實它是我想避免的foreach語句,但是,無論如何,這完全是非常非常感謝! –

0

如果您不需要使用正則表達式,這裏是一個迭代版本的作品:

<?php 
    function remove_quoted_whitespace($str) { 
     $result = ''; 
     $length = strlen($str); 
     $index = 0; 
     $in_quotes = false; 

     while ($index < $length) { 
      $c = $str[$index++]; 

      if ($c == '"') { 
       $in_quotes = !$in_quotes; 
      } else if ($c == ' ') { 
       if ($in_quotes) { 
        continue; 
       } 
      } 

      $result .= $c; 
     } 

     return $result; 
    } 

    $input = '"mission podcast" modcast A B C "D E F"'; 
    $output = remove_quoted_whitespace($input); 

    echo $input . "\n"; 
    echo $output . "\n"; 
?> 
+1

是的,但不會迭代更多的資源密集型,是否需要更長的時間? –

+0

剛剛進行了一次頭對頭的測試,並且(根據我的直覺),正則表達式的實現確實更快。我將它歸結爲本地代碼(PCRE擴展在C中實現)與解釋的PHP代碼之間的區別。 –

0

整個的foreach是沒有必要的!爲此可以使用單線程。

這裏是一個替代空間在引用的字符串代碼。這個想法是,如果一個空格在引號內,它後面跟着奇數個引號。它可以通過正則表達式預覽來完成。

echo preg_replace('{\s+(?!([^"]*"[^"]*")*[^"]*$)}',"x",$str); 

就這樣!怎麼運行的?它匹配所有不包含偶數引號的字符。匹配的空格被x替換。您當然可以將其更改爲任何所需值或將其保留爲空。

+0

如果你沒有關閉引號,這會停止工作,所以想象一個有多個引用文本段的字符串,並且你關閉了一個關閉引用,它變得古怪 – jackrabbithanna