2013-07-02 64 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