带转义引号的引号字符串的正则表达式

如何使用正则表达式获得子字符串 " It's big \"problem "

s = ' function(){  return " It\'s big \"problem  ";  }';
212305 次浏览
/(["\']).*?(?<!\\)(\\\\)*\1/is

应该与任何引号字符串一起工作

人们必须记住,regexp 并不是所有字符串的灵丹妙药。有些东西更简单,做一个光标和线性,手动,寻找。CFL可以轻而易举地解决这个问题,但是没有多少 CFL 实现(afaik)。

/"(?:[^"\\]|\\.)*"/

在 Regex Coach 和 PCRE Workbench 工作。

JavaScript 测试示例:

    var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);

这个来自 nanorc.sample,可以在许多 linux 发行版中找到。它用于 C 风格字符串的语法突显

\"(\\.|[^\"])*\"
"(?:\\"|.)*?"

交替使用 \".传递转义引号,而使用延迟量词 *?可以确保不超过引号字符串的结尾。一起工作。NET Framework RE 类

正如埃法老所说,答案是

/"([^"\\]*(\\.[^"\\]*)*)"/

若要将上述内容应用于单引号或双引号字符串,请使用

/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/

如果从一开始就搜索,也许这个可以工作?

\"((\\\")|[^\\])*\"

更广泛的 https://stackoverflow.com/a/10786066/1794894版本

/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/

此版本还包含

  1. 最小报价长度为50
  2. 额外的引号类型(打开 并关闭 )

Regexpal上乱搞,最后得到这个 regex: (不要问我它是怎么工作的,我几乎不明白,即使我写了 lol)

"(([^"\\]?(\\\\)?)|(\\")+)+"

这里提供的大多数解决方案使用替代重复路径,即(A | B) * 。

您可能会在大输入上遇到堆栈溢出,因为一些模式编译器使用递归来实现这一点。

例如,Java: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993

就像这样: "(?:[^"\\]*(?:\\.)?)*"或 Guy Bedford 提供的解析步骤将减少解析步骤的数量,从而避免大多数堆栈溢出。

/"(?:[^"\\]++|\\.)*+"/

直接从安装了 Perl 5.22.0的 Linux 系统上的 man perlre获得。 作为一种优化,这个正则表达式使用 +*的“正序”形式来防止回溯,因为事先已经知道,没有结束引号的字符串在任何情况下都不会匹配。

这一个工作在 PCRE 上非常完美,并且不会与 StackOverflow 一起下降。

"(.*?[^\\])??((\\\\)+)?+"

说明:

  1. 每个引号字符串都以 Char: "开头;
  2. 它可以包含任意数量的任意字符: .*?{ Lazy match } ; 以非转义字符 [^\\]结尾;
  3. 语句(2)是 Lazy (!)可选的,因为字符串可以为空(“”)
  4. 最后,每个引号字符串都以 Char (")结尾,但是它的前面可以有偶数个转义符号对 (\\\\)+; 它是贪婪(!)可选: ((\\\\)+)?+{贪婪匹配} ,因为字符串可以是空的或者没有结束对!

这里有一个可以同时使用’和’的方法,您可以在开始时轻松地添加其他内容。

("|')(?:\\\1|[^\1])*?\1

it uses the backreference (\1) match exactley what is in the first group (" or ').

http://www.regular-expressions.info/backref.html

以前从未涉及的一个选项是:

  1. 把绳子反过来。
  2. 对反向字符串执行匹配。
  3. 重新反转匹配的字符串。

这还有一个额外的好处,就是能够正确地匹配转义的打开标记。

假设您有以下字符串; String \"this "should" NOT match\" and "this \"should\" match" 在这里,\"this "should" NOT match\"不应该匹配和 "should"应该。 除此之外,this \"should\" match应该匹配,而 \"should\"不应该。

先举个例子。

// The input string.
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"';


// The RegExp.
const regExp = new RegExp(
// Match close
'([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' +
'((?:' +
// Match escaped close quote
'(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' +
// Match everything thats not the close quote
'(?:(?!\\1).)' +
'){0,})' +
// Match open
'(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))',
'g'
);


// Reverse the matched strings.
matches = myString
// Reverse the string.
.split('').reverse().join('')
// '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS'


// Match the quoted
.match(regExp)
// ['"hctam "\dluohs"\ siht"', '"dluohs"']


// Reverse the matches
.map(x => x.split('').reverse().join(''))
// ['"this \"should\" match"', '"should"']


// Re order the matches
.reverse();
// ['"should"', '"this \"should\" match"']

好了,现在来解释一下正则表达式。 这就是 regexp,它可以很容易地分成三个部分,如下所示:

# Part 1
(['"])         # Match a closing quotation mark " or '
(?!            # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\]         # and a single escape
(?![\\])     # As long as that's not followed by an escape
)
# Part 2
((?:          # Match inside the quotes
(?:           # Match option 1:
\1          # Match the closing quote
(?=         # As long as it's followed by
(?:\\\\)* # A pair of escape characters
\\        #
(?![\\])  # As long as that's not followed by an escape
)           # and a single escape
)|            # OR
(?:           # Match option 2:
(?!\1).     # Any character that isn't the closing quote
)
)*)           # Match the group 0 or more times
# Part 3
(\1)           # Match an open quotation mark that is the same as the closing one
(?!            # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\]         # and a single escape
(?![\\])     # As long as that's not followed by an escape
)

这在图像形式上可能要清楚得多: 使用 杰克斯的正规军生成

Github 上的图像(JavaScript 正则表达式可视化工具) 对不起,我没有足够高的声誉,包括图片,所以,它只是一个链接现在。

下面是使用这个稍微高级一点的概念的一个示例函数的要点: https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js

我遇到过类似的问题,试图删除可能会干扰某些文件解析的带引号字符串。

我最终提出了一个两步解决方案,它击败了你能想到的任何令人费解的正则表达式:

 line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful

更容易阅读,可能更有效率。

如果您的 IDE 是 IntelliJ Ideas,那么您可以忘记所有这些令人头疼的问题,将正则表达式存储到一个 String 变量中,当您将其复制粘贴到双引号中时,它将自动更改为可接受的正则表达式格式。

Java 中的例子:

String s = "\"en_usa\":[^\\,\\}]+";

现在您可以在 regexp 或任何地方使用这个变量。