【问题标题】:Regular expression to escape line breaks in a string正则表达式转义字符串中的换行符
【发布时间】:2020-11-19 17:47:25
【问题描述】:

我在 PHP 中有一个包含 Python 代码的字符串,如下所示:

$source_code = "\nprint('Hello\nWorld')\n";

我需要转义单引号或双引号之间的换行符。我想得到类似以下的东西:

$source_code = "\nprint('Hola\\nWorld')\n";

换句话说,只要在单引号或双引号中出现的\n 前面加上\。我现在在 PHP 中有这个,以防找到单引号:

<?php
    $source_code = "\nprint('Hello\nWorld')\n";
    $source_code = preg_replace("/'(.*)(\\n)(.*)'/", "\\n", $source_code);
    echo $source_code;
?>

但我得到:\nprint(\n)\n。但是,预期的字符串应该是:\nprint('Hello\\nWorld')\n

提前致谢!

【问题讨论】:

  • 这是 PHP 代码,即使文本恰好是 python,它也不是与 python 相关的问题。任何带有换行符的文本都可以。我认为应该删除python标签。
  • 好的,谢谢推荐。
  • 通常需要回调来执行此操作,但可以使用\G 锚来完成。不幸的是,您必须考虑隐藏或可能隐藏引号的评论。那么这是一项艰巨的工作。这是可行的,做到了,但是否值得是个问题......
  • cmets 的正则表达式很大。但是,您将有一系列交替,首先跳过/失败 cmets,然后进行报价检查,一个用于单人,一个用于双人。获取它们的内容,然后在替换回调中,用 LF 替换文字 \n 等......
  • 反正这是正则表达式,捕获组1在回调'~(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/|//(?:[^\\\]|\\\(?:\r?\n)?)*?(?:\r?\n|$))(*SKIP)(*FAIL)|("(?:\\\[\S\s]|[^"\\\])*"|\'(?:\\\[\S\s]|[^\'\\\])*\')|(?:[\S\s][^/"\'\\\]*)(*SKIP)(*FAIL)~'中处理

标签: php regex string replace


【解决方案1】:

仅适用于单个字符串。如有必要,请随时扩展。

$source_code = "x=input()\nprint('Hello\nWorld')\n"; // thx for the test @Hugo :)

$match = preg_match('/(["\'])(.*)\1/s', $source_code, $matches);

if ($match) {
    $text = $matches[2];
    $text = str_replace("\n", '\\\\n', $text);
    $source_code = preg_replace('/(.*)((["\']).*\3)(.*)/s', '$1$3' . addslashes($text) . '$3$4', $source_code);
}

var_dump($source_code);

工作example.

【讨论】:

  • 嗨@Pilan 你的代码看起来不错,你给了我新的想法。谢谢!但是,我认为它可以部分工作,例如,如果我们有 "foo = ['1', '2', 3]\nprint('HelloWorld\n')" 与您的代码输出将是 "foo = ['1', '2', 3]\nprint(\', \'2\', 3]\\nprint(\'HelloWorld\\n')" 但正确的输出是 "foo = ['1', '2', 3]\nprint('HelloWorld\\n')"
  • 正如我所说,单字符串:)
【解决方案2】:

可以使用两次替换,第一次是去掉两端的“\n”,然后替换中间的\n

【讨论】:

  • 问题没那么简单,考虑一下我可以有下面的代码"x=input()\nprint('Hello\nWorld')\n",预期的字符串是"x=input()\nprint('Hello\\nWorld')\n"
猜你喜欢
  • 2010-09-21
  • 2012-04-08
相关资源
最近更新 更多