在php中查找并替换带有条件的字符串

时间:2018-03-11 05:09:23

标签: php

我是PHP的新手。我想替换字符串中的某些字符。我的代码如下:

$str="this 'is' a new 'string and i wanna' replace \"in\" \"it here\"";             
$find = [
        '\'', 
        '"'                
    ];

$replace = [
        ['^', '*']
        ['@', '#']                
    ];

$result = null;
$odd = true;
for ($i=0; $i < strlen($str); $i++) {
    if (in_array($str[$i], $find)) {
        $key = array_search($str[$i], $find);
        $result .= $odd ? $replace[$key][0] : $replace[$key][1];
        $odd = !$odd;
    } else {
        $result .= $str[$i];
    }
}            
echo $result;

上述代码的输出是:
this ^is* a new ^string and i wanna* replace @in# @it here#

但我希望输出为:
this ^is* a new 'string and i wanna' replace @in# "it here"

这意味着字符将替换两个引号(左引号和右引号 - 条件是&#39;和&#34;)。对于单引号,如果有左引号或右引号,则不会替换字符串。它将被替换为左右引用。

1 个答案:

答案 0 :(得分:2)

好的,我不知道所有代码都想要完成什么。

但无论如何,这是我的理由

$str = "this 'is' a new 'string and i wanna' replace \"in\" \"it here\"";

$str = preg_replace(["/'([^']+)'/",'/"([^"]+)"/'], ["^$1*", "@$1#"], $str, 1);

print_r($str);

您可以对其进行测试here

Ouptput

this ^is* a new 'string and i wanna' replace @in# "it here"

使用preg_replace和一个相当简单的正则表达式,我们可以替换引号。现在这里的技巧是preg_replace的第四个参数是$count并且定义为:

  

count 如果指定,此变量将填充已完成的替换次数。

因此,将此值设为1会将其限制为仅限第一场比赛。换句话说,它会进行$count替换,或在这种情况下1。现在因为它是一组模式,每个模式都是分开处理的。所以每个人基本上都被视为一个单独的操作,因此每个人都可以进行$count次匹配,或者每次获得1次匹配/替换。

现在不管是否适用于我所说的每一个用例,但对于您提供的示例,它是最直接的方式。

至于比赛本身/'([^']+)'/

  • /开启和关闭&#34;分隔符&#34;对于表达式(它是必需的,但它不必是/
  • '字面匹配,匹配'一次(开头报价)
  • ( ... )捕获组(group1),因此我们可以在替换中使用它,如$1
  • 带有[^']+非修饰符的
  • [^字符集,匹配不在集合中的任何内容,因此任何不是'一次或多次的内容,贪婪
  • '文字匹配,匹配'一次(结束引用)

替换"^$1*"

  • ^ literal,在
  • 中添加此字符
  • $1使用捕获组(group1)的内容
  • * literal,在
  • 中添加char

希望有助于了解它是如何运作的。

<强>更新

好吧我想我最终破译了你想要的东西:

  如果任何单词有左右引号,

字符串将被替换。例如..&#39; word&#39; ..这里的字符串将被更改..但是&#39;字......在这种情况下不会改变或字'&#39;也不要改变。

这似乎是你只想说&#34;整个&#34;没有空格的单词。

因此,在这种情况下,我们必须像这样调整正则表达式:

 $str = preg_replace(["/'([-\w]+)'/",'/"([-\w]+)"/'], ["^$1*", "@$1#"], $str);

所以我们删除了限制$count,我们将字符组中的内容更改为更严格:

  • [-\w]+ \w表示工作集,换句话说a-zA-Z0-9_-是文字(在这种情况下,它必须/应该先行)

我们对此的看法是仅匹配以引号(单|双)开头和结尾的字符串,并且仅当它们中的字符串与工作集和连字符匹配时才匹配。这不包括空间。这种方式在第一种情况下,你的例子,它产生相同的结果,但如果你要将它翻转到

 //[ORIGINAL] this 'is' a new 'string and i wanna' replace \"in\" \"it here\"
 this a new 'string and i wanna' replace  'is' \"it here\" \"in\"

你会得到他的输出

this a new 'string and i wanna' replace  ^is* \"it here\" @in#

在改变之前你会得到

this a new ^string and i wanna* replace  'is' @it here# "in"

换句话说,它只会替换第一次出现,现在它将替换引号之间的任何内容,当且仅当它是一个完整的单词时。

作为最后一点,如果您只想通过将字符集更改为此[a-zA-Z]+来想要字母字符,那么您可以更加严格,那么它只会与a匹配到z,{ {1}}或upper案例。以上示例将lower0(或它们的任意组合)匹配9连字符,-下划线和前面提到的字母集。

希望这就是你所需要的。