在Javascript正则表达式中替换未被单引号包围的双引号

3

我需要的是一个正则表达式,只选择不被单引号包围的双引号。(这是为了快速将双引号重构为单引号而不破坏任何嵌套字符串)。

示例(与此处相同):

"foo" => 'foo'
'foo' => 'foo'
abc "foo" => abc 'foo'
foo "bar", "baz" => foo 'bar', 'baz'
abc 'foo "bar" baz' => abc 'foo "bar" baz'

在查找这个问题时,我能够找到如何在PCRE中实现此功能,但我无法想出如何将(*SKIP)(*F)转换为可用的JavaScript Regex。
我的JavaScript尝试是:/(?:('.*["].*')|")/g (演示)。
第一个模式/'.*["].*'/可以很好地匹配我最终想要排除的内容('foo "bar" baz'),但我不确定如何告诉表达式,如果匹配了它,则将其排除。
我已经尝试使用(?!)表达式进行操作,但没有成功。
如果有人有关于如何编写更好的正则表达式或解决问题的替代方案的想法,我会感激不尽。
编辑:
作为附加信息,这些正则表达式被用于WebStorm / PHPStorm中的搜索和替换功能以重构源代码。

如果使用提到的 (*SKIP)(*FAIL) 机制,这将会容易得多。 - Jan
是的,它会!不幸的是,在该程序中它不是有效的正则表达式。 - Hanna
你不能在相关代码上运行一个脚本吗?这实际上只需要大约五行代码。如果这不是一个选项,请查看http://www.rexegg.com/regex-best-trick.html并向下滚动到“JS”部分 - 但即使如此,这也需要完整的JavaScript功能,而PHPStorm可能没有(未经测试)。 - Jan
Jan,实际上这是个好想法。你在这方面有什么推荐(软件/脚本)吗? - Hanna
2个回答

4
您可以使用以下正则表达式:
"(?=(?:[^']*'[^']*')*[^']*$)

它将匹配单引号外的任何双引号,工作样例

关键在于向前搜索到行尾,找到一对单引号,如果发现单引号数为奇数,则不接受。


这真的很棒,考拉 - 谢谢你的解释。这个方法是否也容易扩展到排除双引号中包含单引号的情况? - Hanna
是的,正则表达式"([^'\n]+)"(?=(?:[^']*'[^']*')*[^']*$)现在将匹配整个文本并捕获内容,因此您需要用'$1'替换。 - Leonardo Xavier

2
除了评论之外:
<?php

$data = <<<DATA
"foo"
'foo'
abc "foo"
foo "bar", "baz"
abc 'foo "bar" baz'
DATA;

$regex = "~
        '[^']*'(*SKIP)(*FAIL) # match everything between single quotes and fail 
        |                     # or
        \"([^\"]*)\"          # match double quotes
        ~x";

$data = preg_replace($regex, "'$1'", $data);

echo $data;
?>

请查看在ideone.com上的演示


哦,这个问题要求的是 JavaScript 代码,不是 PHP 代码? - Bergi
@Bergi:当然,你是对的,但请阅读评论部分。 - Jan
1
感谢Jan的付出,我很感激。 - Hanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接