0

我在这里遇到一个问题,试图在某种条件下用另一个替换字符串。检查示例:

$data = '
tony is playing with toys.
tony is playing with "those toys that are not his" ';

所以我想用卡片代替玩具。但只有不在 ques ( " ) 中。

我知道如何替换所有玩具词 。

$data = str_replace("toys", "cards",$data);

但我不知道如何添加一个条件,指定仅替换不在 ( " ) 中的条件。

有人可以帮忙吗?

4

3 回答 3

0

您可以使用正则表达式并使用否定环视来查找不带引号的行,然后对其进行字符串替换。

^((?!\"(.+)?toys(.+)?\").)*

例如

preg_match('/^((?!\"(.+)?toys(.+)?\").)*/', $data, $matches);
$line_to_replace = $matches[0];
$string_with_cards = str_replace("toys", "cards", $line_to_replace);

或者,如果有多个匹配项,您可能想要遍历数组。

http://rubular.com/r/t7epW0Tbqi

于 2013-11-07T23:13:03.437 回答
0

您需要解析字符串以识别不在引号内的区域。您可以使用支持计数的状态机或正则表达式来执行此操作。

这是一个伪代码示例:

typedef Pair<int,int> Region;
List<Region> regions;

bool inQuotes = false;
int start = 0;
for(int i=0;i<str.length;i++) {
    char c = str[i];
    if( !inQuotes && c == '"' ) {
        start = i;
        inQuotes = true;
    } else if( inQuotes && c == '"' ) {
        regions.add( new Region( start, i ) );
        inQuotes = false;
    }

}

然后根据 拆分字符串regions,每个备用区域将用引号引起来。

对读者的挑战:获取它以便处理转义的引号 :)

于 2013-11-07T23:11:27.250 回答
-1

这是一种简单的方法。使用引号拆分/分解您的字符串。结果数组中的第一个 ( 0-index) 元素和每个偶数索引是不带引号的文本;奇数在引号内。例子:

Test "testing 123" Test etc.
^0    ^1          ^2

然后,仅在偶数数组元素中将魔术词(玩具)替换为替换(卡片)。

示例代码:

function replace_not_quoted($needle, $replace, $haystack) {
    $arydata = explode('"', $haystack);

    $count = count($arydata);
    for($s = 0; $s < $count; $s+=2) {
        $arydata[$s] = preg_replace('~'.preg_quote($needle, '~').'~', $replace, $arydata[$s]);
    }
    return implode($arydata, '"');
}

$data = 'tony is playing with toys.
tony is playing with toys... "those toys that are not his" but they are "nice toys," those toys';

echo replace_not_quoted('toys', 'cards', $data);

所以,这里的样本数据是:

tony is playing with toys.
tony is playing with toys... "those toys that are not his" but they are "nice toys," those toys

该算法按预期工作并产生:

tony is playing with cards.
tony is playing with cards... "those toys that are not his" but they are "nice toys," those cards
于 2013-11-08T01:10:54.460 回答