使用正则表达式转义单引号字符串中的所有双引号 [重复]

Posted

技术标签:

【中文标题】使用正则表达式转义单引号字符串中的所有双引号 [重复]【英文标题】:Escape all double quotes inside a single quoted string with Regex [duplicate] 【发布时间】:2011-05-03 15:41:29 【问题描述】:

可能重复:Regular Expression to escape double quotes inside single quotes

我需要一个正则表达式(没有其他语言!!,最好是 perl 语法 REGEX 或 PCRE 语法 REGEX)将所有双引号 " 替换为单引号字符串中的 \"。这是一个示例字符串(文件的一部分):

var baseUrl = $("#baseurl").html();
var head = '<div id="finishingDiv" style="background-image:url(baseUrlcss/userAd/images/out_main.jpg); background-repeat: repeat-y; ">'+
'<div id="buttonbar" style="width:810px; text-align:right">';

(请注意:它们不必成对成对“someValueBetween”,因此一个单引号字符串中可能存在奇数个双引号。)

这应该是上面最后一行的最终结果:

'<div id=\"buttonbar\" style=\"width:810px; text-align:right\">';

提前致谢

***更新: 为了清楚起见,我只想要一个正则表达式,而不是 perl 程序。正则表达式可以是 perl 正则表达式语法或 php PCRE 语法(据我了解,这是与 perl 正则表达式语法非常接近的语法)。目标是您可以在 IDES 中运行正则表达式在搜索和替换支持正则表达式的菜单(如 Eclipse 和 PhpEd f.e)!!

换句话说,我想要一个正则表达式,我将把它放在搜索 IDE 字段中,从而在单引号字符串中为我提供完全未转义的 "。在 Eclipse 的替换字段中,我可以输入 \$1 来逃避它们。

他们应该在 Regexbuddy 或 regex coach 工作,所以我可以测试他们。

至少这是计划:)


【问题讨论】:

正则表达式比正则表达式字符串的斜线更容易——您是否正在寻找一个将斜线“s”的 javascript 函数? 不,我特别在寻找正则表达式,而不是 javascript、php 或 perl 函数。它应该是一个简单的正则表达式,它在一个单引号字符串中检索所有未正确转义的 "s 以用 \" 替换它们(可能是 $1 或其他东西) 【参考方案1】:

你只要求 Perl(或 PCRE),没有别的。

好的。

如果您只想转义未转义的双引号,无论您在哪里找到它们,请执行以下操作:

  s
      (?<! (?<! \\ ) \\1 )
      (?<! (?<! \\ ) \\3 )
      (?<! (?<! \\ ) \\5 )
      (?<! (?<! \\ ) \\7 )
      (?= " )
  \\xg;

如果您想在未转义的单引号之间转义未转义的双引号,并且您只有一对这样的单引号,请执行以下操作:

1 while s

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\1 )
      (?<! (?<! \\ ) \\3 )
      (?<! (?<! \\ ) \\5 )
      (?<! (?<! \\ ) \\7 )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<double_quote> (?&unescaped) " )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD>
    (?&single_quote)
    (?&unquoted)
  )

  (?<TAIL>
    (?&double_quote)
    (?&unquoted)
    (?&single_quote)

  )

<$+HEAD\\$+TAIL>xg;

但是,如果您每行可能有多组成对的非转义单引号,并且您只想转义位于这些非转义单引号之间的非转义双引号,那么请执行以下操作:

sub escape_quote 
  my $_ = shift;
  s
      (?<! (?<! \\ ) \\1 )
      (?<! (?<! \\ ) \\3 )
      (?<! (?<! \\ ) \\5 )
      (?<! (?<! \\ ) \\7 )
      (?= " )
  \\xg;

  return $_;


s

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\1 )
      (?<! (?<! \\ ) \\3 )
      (?<! (?<! \\ ) \\5 )
      (?<! (?<! \\ ) \\7 )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD> (?&single_quote) )
  (?<TARGET> (?&unquoted) )
  (?<TAIL> (?&single_quote) )


               $+HEAD    .
  escape_quote($+TARGET) .
               $+TAIL

xeg;

请注意,这一切都假定您没有包含未转义单引号的合法配对未转义双引号。即使是这样的事情也会让你失望:

my $cute = q(') . "stuff" . q(');

不过,您可能想使用适当的解析模块。

请不要注意所有花哨和欺骗性不正确的 SO 着色。由于某种原因,它似乎无法像 perl 那样解析 Perl。无法想象为什么。 ☺

【讨论】:

看起来令人印象深刻的男人!!!是否有机会在 regexbuddy 或 regex coach 中运行它,尤其是在 eclipse 中运行它作为搜索替换正则表达式? (你在为 Perl 工作吗?) @Tschef: Wikipedia on tchrist 好的,你有自己的***条目。我必须说令人印象深刻。我在你面前鞠躬 :) 这个正则表达式的 Eclipse 搜索和替换部分有什么帮助吗?不幸的是,我不能强迫团队中的每个人都安装 perl。【参考方案2】:

根据您的编辑,您希望在未指定的 IDE 或文本编辑器的搜索和替换功能中使用通用正则表达式。没那么简单。我相信您知道不同的语言(Perl、Java、Python 等)往往有自己的正则表达式风格,具有不同的功能集和语法怪癖。编辑器和 IDE 之间的情况更糟。

更新:自从我写了这篇文章后,Visual Studio 已经切换到使用 .NET 风格,并且 Notepad++ 已经采用了 Boost 库。下面的正则表达式现在可以在我提到的除 Visual Studio 之外的所有编辑器/IDE 中使用。 (.NET 不支持所有格量​​词,但它确实有原子组,可以用于相同的效果。)

JEdit 和 IntelliJ IDEA 是用 Java 编写的,使用 Java 的正则表达式风格,这非常好。但是 Visual Studio 确实使用出色的 .NET 风格;相反,它使用具有折衷功能集和奇怪语法的传统风格。 TextMate 是 Apple 开发人员赞不绝口的 Mac 编辑器,它使用功能丰富的 Oniguruma 风格,但 Notepad++(一个免费的 Windows 编辑器,也获得了很多好评)使用的风格非常有限——它没有甚至支持轮换!

因此,根据您使用的编辑器,即使是相对简单的任务也可能很困难或不可能,但您尝试做的事情非常棘手。这是我想出的最简单的正则表达式:

搜索: \G((?:(?:\A|')[^']*+')?+[^'"]*+)"([^'"]*+)

替换: $1\\"$2

(假设每个撇号都用作引号;它们都不需要被忽略,因为它们在 cmets、双引号字符串或其他中;已经没有转义引号(单引号或双引号)文本;列表还在继续。)

\Gend-of-previous-match 锚点)是必不可少的,但即使是一些更流行的正则表达式风格(如 JavaScript 和Python。占有量词 (*+, ?+) 防止正则表达式在无法匹配时陷入困境;它们在 PCRE、Oniguruma、Perl 5.10+ 和 Java 中可用。 .NET 没有它们,但它确实有一些更笨拙的替代方案,原子组。

我建议您忘记通用正则表达式方法,并使用具有您需要的功能的工具集进行标准化。出于一般目的,我认为没有什么能胜过 JGSoft 工具系列:EditPad Pro、PowerGrep 和 RegexBuddy。在功能和性能方面,JGSoft 正则表达式风格与现有的任何东西一样好;它所缺少的只是递归匹配和嵌入代码功能。

p.s. 我看到你在评论中提到了 Eclipse;我没有安装它,但我希望它使用 Java 的正则表达式风格(或者可能是 ICU 风格,其语法几乎与 Java 相同),所以上面的正则表达式应该可以在其中工作。

【讨论】:

这实际上很接近,但使用 \G 它并没有真正起作用。它在正则表达式语法中有 \G 选项,但不能使用它!如果我把它排除在外,如果弄乱了正则表达式,我猜是因为它所做的就是转义所有“”,无论它们在哪里或是否在单引号中。有没有机会让这个语句以某种方式逐行工作。那我就足够了猜测。 这是在 Eclipse 中吗?可能是您必须以不同的方式逃避事物。以下是它在(正常工作)Java 代码中的样子:replaceAll("\\G((?:(?:\\A|')[^']*+')?+[^'\"]*+)\"([^'\"]*+)", "$1\\\\\"$2") 我不希望编辑器的搜索小部件需要所有转义,但也许...... 语法很好,但是前面的 \G 并没有令人惊讶地发现任何东西。根据 eclipse 正则表达式语法,它支持 \G 和 \A。其余的也很好,而且总是只有一个斜线。你能告诉我 \G 和 \A 到底是做什么的吗,其余的可以理解,尽管我自己永远不会明白:)【参考方案3】:

只要每行只有一个单引号字符串(如您的示例所示),这应该有效(sed 语法):

s|'\([^'"]*\)"\([^']*\)'|'\1\"\2'|g

【讨论】:

@Downvoter:我认为这是使用一个正则表达式的最佳解决方案。 这是一个无效的 Perl 正则表达式,或者至少是一个不正确且不明智的表达式。首先,您不应该将\1 等放在替换的RHS 中。其次,如果您希望填充捕获组,则不应在 LHS 中转义括号。第三,有很多场景你没有考虑到。 不幸的是,在使用 Perl 语法的 RegexBuddy 中根本不起作用。我不明白捕获组应该如何与前面的 \ 一起工作。不过还是希望能理解 @Tschef:至少在 GNU sed 4.2.1 中,您必须对括号进行转义以赋予它们特殊的含义。

以上是关于使用正则表达式转义单引号字符串中的所有双引号 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

python 单个正则表达式,用于解析Python单引号或双引号字符串,同时保留任何转义的引号字符

具有奇怪行为的正则表达式:将字符串与反向引用匹配以允许转义以及单引号和双引号

php用正则表达式怎么取双引号里面的内容??

正则表达式

java正则转义json中双引号

正则表达式删去双引号vscode