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

问题描述 投票:0回答:17

如何使用正则表达式获取子字符串

" It's big \"problem  "

s = ' function(){  return " It\'s big \"problem  ";  }';     
regex escaping quotes
17个回答
203
投票
/"(?:[^"\\]|\\.)*"/

适用于 Regex Coach 和 PCRE Workbench。

JavaScript 测试示例:

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


40
投票

这个来自许多 linux 发行版中的 nanorc.sample。它用于 C 风格字符串的语法高亮

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

23
投票

由ePharaoh提供,答案是

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

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

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

12
投票

此处提供的大多数解决方案都使用替代重复路径,即 (A|B)*.

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

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

像这样:

"(?:[^"\\]*(?:\\.)?)*"
,或者由 Guy Bedford 提供的那个将减少解析步骤的数量,避免大多数堆栈溢出。


11
投票
/(["\']).*?(?<!\\)(\\\\)*\1/is

应该适用于任何带引号的字符串


9
投票
"(?:\\"|.)*?"

交替使用

\"
.
传递转义引号,而惰性量词
*?
确保您不会越过引号字符串的末尾。与 .NET Framework RE 类一起工作


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

直接取自

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


5
投票

这个在 PCRE 上工作完美,不会与 StackOverflow 一起使用。

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

说明:

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

3
投票

一个之前没接触过的选项是:

  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
)

这在图像形式上可能更清晰:使用 Jex 的 Regulex 生成

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

这里是一个使用这个概念的示例函数的要点,它更高级一些:https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js


2
投票

这里有一个同时使用 " 和 ' 的,你可以在开始时轻松添加其他的。

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

它使用反向引用 ( ) 精确匹配第一组(" 或 ')中的内容。

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


0
投票

必须记住,正则表达式并不是解决所有字符串问题的灵丹妙药。有些东西用光标和线性、手动、搜索更容易完成。 CFL 可以很简单地完成这个技巧,但是 CFL 实现并不多(afaik)。


0
投票

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

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

此版本还包含

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

0
投票

如果从头开始搜索,也许这样可行?

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

0
投票

我在尝试删除可能会干扰某些文件解析的引号字符串时遇到了类似的问题。

我最终得到了一个两步解决方案,它击败了你能想到的任何复杂的正则表达式:

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

更容易阅读并且可能更有效率。


0
投票

如果您的 IDE 是 IntelliJ Idea,您可以忘记所有这些令人头疼的事情,将您的正则表达式存储到一个字符串变量中,当您将其复制粘贴到双引号内时,它会自动更改为正则表达式可接受的格式。

Java 中的例子:

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

现在您可以在正则表达式或任何地方使用此变量。


0
投票
(?<="|')(?:[^"\\]|\\.)*(?="|')

“这是个大”问题“ 比赛结果: 这是个大“问题”

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

“这是个大”问题“ 比赛结果: “这是个大”问题“


-1
投票

regexpal 上搞砸了,最后得到了这个正则表达式:(不要问我它是如何工作的,我什至几乎不明白我写的哈哈)

"(([^"\\]?(\\\\)?)|(\\")+)+"
© www.soinside.com 2019 - 2024. All rights reserved.