3

可能重复:
正则表达式转义单引号内的双引号

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

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 正则表达式语法或 PHP PCRE 语法(据我了解,这是与 perl 正则表达式语法非常接近的语法)。目标是您可以在 IDES 中运行正则表达式,在搜索和替换支持正则表达式的菜单(如 Eclipse 和 PhpEd fe )!

换句话说,我想要一个正则表达式,我将把它放在搜索 IDE 字段中,"结果是我在单引号字符串中完全没有转义。在 Eclipse 的替换字段中,我可以将\$1它们转义。

他们应该在 Regexbuddy 或 regex coach 中工作,这样我就可以测试他们了。

至少这是计划:)


4

3 回答 3

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

不过,您可能想要使用正确的解析模块。

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

于 2010-11-01T23:26:57.090 回答
2

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

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

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

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

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

代替: $1\\"$2

(这假设每个撇号都用作引号;不需要忽略它们,因为它们位于注释、双引号字符串或其他任何内容中;文本中已经没有转义引号(单引号或双引号);而这样的例子不胜枚举。)

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

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

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

于 2010-11-02T10:26:31.140 回答
0

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

s|'\([^'"]*\)"\([^']*\)'|'\1\"\2'|g
于 2010-11-01T21:25:54.340 回答