PHP Regex替换类似字符串

时间:2017-12-05 08:37:26

标签: php regex string

我有一个包含集合字符串的文件。所有字符串都以相同的字符集开头,并以相同的字符结尾。我需要找到与特定模式匹配的所有字符串,然后在保存文件之前从中删除特定字符。每个字符串如下所示:

Data_*: " ... "

其中Data_对于每个字符串是相同的,星号是一个递增的整数,可以是两位或三位数,而冒号和双引号对于每个字符串都是相同的。 ...在每个字符串中完全不同,它是我需要处理的部分。我需要删除...中的所有双引号,保留封闭的双引号。我不需要更换它们,只需将它们移除即可。

所以,例如,我需要这个......

Data_83: "He said, "Yes!" to the question"

成为这个...

Data_83: "He said, Yes! to the question"

我熟悉PHP并希望使用它。我知道怎么做......

<?php
$filename = 'path/to/file';
$content = file_get_contents($filename);
$new_content = str_replace('"', '', $content);
file_put_contents($filename, $new_content);

我非常确定正则表达式将是我想要用来查找字符串并删除额外的双引号。但我对正则表达式很新,需要一些帮助。

编辑:

我应该提到,该文件是一个包含对象的PHP文件。看起来有点像这样:

<?php
$thing = {
    Data_83: "He said, "Yes!" to the question",
    Data_84: "Another string with "unwanted" quotes"
}

4 个答案:

答案 0 :(得分:3)

您可以将preg_replace_callback与正则表达式

一起使用
'~^(\h*Data_\d{2,}:\h*")(.*)"~m'

请注意,如果您在行末{?1}}指定了可选,,则可能会更安全,但您可能需要引入另一个捕获组('~^(\h*Data_\d{2,}:\h*")(.*)",?\h*$~m'左右,然后在,?\h*回调函数中附加$m[3]

<强>详情

  • preg_replace_callback - 行的开头(^是多行修饰符)
  • m - 第1组((\h*Data_\d{2,}:\h*")):
    • $m[1] - 0+水平空格
    • \h* - Data_ substring
    • Data_ - 2位或更多位数
    • \d{2,} - 冒号
    • : - 0+水平空格
    • \h* - 双引号
  • " - 第2组((.*)):除了换行符之外的任何0 +字符,尽可能多,直到最后......
  • $m[2] - 双引号(在一条线上)。

"表示整个匹配对象,您只需删除$m内的",即第二次捕获。

请参阅PHP demo

$m[2]

答案 1 :(得分:1)

不那么优雅,但你可以创建一个UDF:

function RemoveNestedQuotes($string)
{
    $firstPart = explode(":", $string)[0];
    preg_match('/"(.*)"/', $string, $matches, PREG_OFFSET_CAPTURE);
    $tmpString = $matches[1][0];
    return $firstPart . ': "' . preg_replace('/"/', '', $tmpString) . '"';
}

示例:

$string = 'Data_83: "He said, "Yes!" to the question"';

echo RemoveNestedQuotes($string);

// Data_83: "He said, Yes! to the question" 

答案 2 :(得分:0)

str_replace implodeexplode之后的又一步。你可以这样做。

<?php
$string = 'Data_83: "He said, "Yes!" to the question"';
$string = str_replace('"', '', $string);
echo $string =implode(': "',explode(': ',$string)).'"';
?>

演示:https://eval.in/912466

节目输出

Data_83: "He said, Yes! to the question"

只需替换"引号

<?php
$string = 'Data_83: "He said, "Yes!" to the question"';
echo preg_replace('/"/', '', $string);
?>

演示:https://eval.in/912457

答案 3 :(得分:0)

我看到它的方式,你不需要进行任何preg_replace_callback()电话或一次令人费解的爆炸和更换。您只需取消您希望保留的2个双引号的资格,并将其余引号与其他引号相匹配。

代码:(Demo

$string = 'Data_83: "He said, "Yes!" to the question",
Data_184: "He said, "WTF!" to the question"';

echo preg_replace('/^[^"]+"(*SKIP)(*FAIL)|"(?!,\R|$)/m','',$string);

输出:

Data_83: "He said, Yes! to the question",
Data_184: "He said, WTF! to the question"

Pattern Demo

/^[^"]+"(*SKIP)(*FAIL)|"(?!,?$)/m

这种模式说:

  • 从每行的开头匹配,直到达到第一个双引号,然后取消它。
  • 然后在|之后,匹配所有双引号,这些双引号后面没有逗号,然后是行尾。

虽然这个模式使用我的示例输入在regex101上运行,但是当我将它转移到php沙箱中以重新组合演示时,我需要添加\R以保持准确性。您可以测试以查看哪个适合您的服务器/环境。