使用Regex在单引号字符串中转义所有双引号

时间:2010-11-01 21:16:11

标签: regex perl escaping quotes substitution

  

可能重复:
  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({baseUrl}css/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 regex语法或PHP PCRE语法(根据我的理解,这是一种非常接近perl regex语法的语法)。目标是你可以在搜索中运行IDES中的正则表达式并替换支持正则表达式的菜单(如Eclipse和PhpEd f.e)!!

换句话说,我想要一个正则表达式,我将把它放在搜索IDE字段中,结果是在单引号字符串中给出了我所有未转义的"。在eclipse的替换字段中,我可以放\$1来逃避它们。

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

至少那是计划:)


3 个答案:

答案 0 :(得分:4)

您要求使用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(');

但是,您可能希望使用正确的解析模块。

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

答案 1 :(得分:2)

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

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

用Java编写的JEdit和IntelliJ IDEA使用Java的正则表达式,非常好。但Visual Studio确实使用优秀的.NET风格;相反,它使用具有折衷功能集和奇怪语法的传统风味。 TextMate是苹果公司开发的Mac编辑器,它使用了功能丰富的Oniguruma风格,但Notepad ++(一个免费的Windows编辑器也获得了很多好的新闻)使用的功能极其有限 - 它没有甚至支持轮换!

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

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

替换: $1\\"$2

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

\G上一个匹配的锚点)是必不可少的,但这是一项功能,即使是一些比较流行的正则表达式,也不支持JavaScript和Python。占有量词(*+?+)可以防止正则表达式在不可能匹配时陷入困境;它们可用于PCRE,Oniguruma,Perl 5.10+和Java。 .NET没有它们,但它确实有一些有点笨拙的替代原子组。

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

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

答案 2 :(得分:0)

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

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