PHP正则表达式替换类似字符串中字符的所有实例

PHP正则表达式替换类似字符串中字符的所有实例,php,regex,string,Php,Regex,String,我有一个包含集合字符串的文件。所有字符串都以相同的字符集开始,以相同的字符结束。我需要找到与某个模式匹配的所有字符串,然后在保存文件之前删除其中的特定字符。每个字符串如下所示: Data_*: " ... " <?php $thing = { Data_83: "He said, "Yes!" to the question", Data_84: "Another string with "unwanted" quotes" } 其中,数据对于每个字符串都是相同的,星号

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

Data_*: " ... "
<?php
$thing = {
    Data_83: "He said, "Yes!" to the question",
    Data_84: "Another string with "unwanted" quotes"
}
其中,
数据
对于每个字符串都是相同的,星号是两位或三位的递增整数,冒号和双引号对于每个字符串都是相同的。
在每个字符串中都是完全不同的,这是我需要处理的每个字符串的一部分。我需要删除
中的所有双引号,保留所包含的双引号。我不需要更换它们,只要把它们取下来就行了

例如,我需要这个

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);

str\u之后再执行一步,将
替换为
内爆
爆炸
。你可以这样做

<?php
$string = 'Data_83: "He said, "Yes!" to the question"';
$string = str_replace('"', '', $string);
echo $string =implode(': "',explode(': ',$string)).'"';
?>
只是为了替换
引号

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


演示:

您可以使用类似正则表达式的
preg\u replace\u callback

'~^(\h*Data_\d{2,}:\h*")(.*)"~m'
请注意,如果在行尾指定一个可选的
,(\h*Data\ud{2,}:\h*”(.*),?\h*$~m'
,可能会更安全,但您可能需要引入另一个捕获组(在
,?\h*
,然后在
preg\u replace\u回调
回调函数中追加
$m[3]

详细信息

  • ^
    -行的开头(
    m
    是多行修饰符)
  • (\h*数据{2,}:\h*”
    -第1组(
    $m[1]
    ):
    • \h*
      -0+水平空白
    • 数据
      -
      数据
      子字符串
    • \d{2,}
      -2位或更多数字
    • -冒号
    • \h*
      -0+水平空白
    • -双引号
  • (.*)
    -第2组(
    $m[2]
    ):除换行符以外的任何0+字符,尽可能多,直到最后一个
  • -双引号(在一行上)
$m
表示整个匹配对象,您只需删除
$m[2]
内的
,即第二个捕获

见:


虽然没有那么优雅,但您可以创建一个自定义项:

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" 

在我看来,您不需要进行任何
preg\u replace\u callback()
调用或复杂的爆炸和替换运行。您只需取消希望保留的两个双引号的资格,并将其余的双引号匹配以删除

代码:()

输出:

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

这种模式表示:

  • 从每行开始匹配,直到到达第一个双引号,然后取消其资格
  • 然后,在
    |
    之后,匹配所有不可选后跟逗号的双引号,然后是行尾

虽然这个模式在我的示例输入的regex101上工作,但当我将它转移到php沙箱来制作一个演示时,我需要添加
\R
,以保持准确性。您可以测试哪种模式适合您的服务器/环境。

您的文件的格式是什么?json?对不起,我应该提到,它是一个php文件包含关联数组但引号内的引号将引发解析错误它不是关联数组在此关联数组上应用foreach
str\u replace
。此外,您显示的数组既不是关联数组也不是数组({}不是数组的表示形式)“83”和引号之间的内容对于每个字符串都是不同的,我有数千个引号them@PeterCullen:因此,只需使用第二个示例中的
preg\u replace
,但这也将替换引号。应该在那里。您的答案非常清楚准确,但OP已更改其要求,并且给定的条件也已更改区别。@RishiRaut此解决方案必须适用于问题中
EDIT
一词后面提到的场景。如果有其他情况,它可以很容易地进行调整。扩展此答案,如果您想不使用双引号将其作为实际内容,而不是替换它们,请按如下方式编辑str_replace:
 返回$m[1].str_replace(“”、“\\”、$m[2])。“我认为Stribizew是对的,上面的答案在我的情况下不起作用,但它仍然得到了我的支持,因为它是如此彻底和解释这是富有成效的。谢谢我决定使用这个方法,在每个PHP_EOL分解文件内容,得到一个行数组,然后将上面的答案应用到每一行,并将它们添加到要写入文件的结果字符串中。我必须检查$matches[1][0]是否与每一行一起返回,如果设置了preg_replace(isset),则仅将其应用于该行,否则只需将该行添加到结果中。再次感谢。@PeterCullen这是一种干净/直接的单次调用替换方法。如果这不适用于您的项目,请澄清问题所在,以便我可以更新我的答案。
$string = 'Data_83: "He said, "Yes!" to the question"';

echo RemoveNestedQuotes($string);

// Data_83: "He said, Yes! to the question" 
$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"
/^[^"]+"(*SKIP)(*FAIL)|"(?!,?$)/m