提问人: 提问时间:10/30/2008 最后编辑:David 更新时间:2/23/2023 访问量:227762
带转义引号的带引号的字符串的正则表达式
Regex for quoted string with escaping quotes
问:
如何使用正则表达式获取子字符串?" It's big \"problem "
s = ' function(){ return " It\'s big \"problem "; }';
答:
/(["\']).*?(?<!\\)(\\\\)*\1/is
应该与任何带引号的字符串一起使用
评论
"Martha's"
"Martha'
人们必须记住,正则表达式并不是解决所有字符串问题的灵丹妙药。有些东西用光标和线性、手动、搜索更简单。CFL 可以非常轻松地解决问题,但 CFL 实现 (afaik) 并不多。
评论
/"(?:[^"\\]|\\.)*"/
在 The Regex Coach 和 PCRE Workbench 中工作。
JavaScript 测试示例:
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
评论
(?:...)
/(["'])(?:[^\1\\]|\\.)*?\1/
这个来自许多 linux 发行版中可用的 nanorc.sample。它用于 C 样式字符串的语法高亮显示
\"(\\.|[^\"])*\"
评论
string 和 \“this should be matched\”';
,这种方法将导致意想不到的结果。
" \"(\\\\.|[^\\\"])*\" "
"(?:\\"|.)*?"
交替使用 和 传递转义的引号,而惰性量词可确保不会超过带引号的字符串的末尾。适用于 .NET Framework RE 类\"
.
*?
评论
"\\"
string 和 \“this should be matched\”';
/"(?:(?:\\"|[^"])*)"/g
这应该可以解决
正如 ePharaoh 所提供的,答案是
/"([^"\\]*(\\.[^"\\]*)*)"/
要使上述内容适用于单引号或双引号字符串,请使用
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
评论
如果从一开始就搜索,也许这可以工作?
\"((\\\")|[^\\])*\"
https://stackoverflow.com/a/10786066/1794894 的更广泛版本
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
此版本还包含
- 最小报价长度为 50
- 额外类型的报价(打开和关闭
“
”
)
在正则表达式上搞砸了,最终得到了这个正则表达式:(不要问我它是如何工作的,即使我写了它,我也几乎不明白哈哈)
"(([^"\\]?(\\\\)?)|(\\")+)+"
此处提供的大多数解决方案都使用替代重复路径,即 (A|B)*.
您可能会在大型输入上遇到堆栈溢出,因为某些模式编译器使用递归来实现这一点。
例如,Java:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993
像这样: ,或者 Guy Bedford 提供的那个将减少解析步骤的数量,避免大多数堆栈溢出。"(?:[^"\\]*(?:\\.)?)*"
/"(?:[^"\\]++|\\.)*+"/
直接从安装了 Perl 5.22.0 的 Linux 系统上获取。
作为优化,此正则表达式使用两者的“posessive”形式,并防止回溯,因为事先知道没有结束引号的字符串在任何情况下都不会匹配。man perlre
+
*
这个在 PCRE 上工作得很好,不会与 StackOverflow 一起使用。
"(.*?[^\\])??((\\\\)+)?+"
解释:
- 每个带引号的字符串都以 Char 开头:
"
; - 它可以包含任意数量的任何字符:{Lazy match};以非转义字符结尾
.*?
[^\\]
; - 语句 (2) 是 Lazy(!) 可选的,因为字符串可以是空的(“”)。所以:
(.*?[^\\])??
- 最后,每个带引号的字符串都以 Char() 结尾,但它前面可以有偶数个转义符号对;它是 Greedy(!) 可选的: {Greedy matching}, bacause string 可以是空的,也可以没有结束对!
"
(\\\\)+
((\\\\)+)?+
评论
"(.*?[^\\])?(\\\\)*"
这是一个同时使用“ 和 ' 的,您可以在开始时轻松添加其他的。
("|')(?:\\\1|[^\1])*?\1
它使用反向引用 (\1) 与第一组(“或”)中的内容完全匹配。
http://www.regular-expressions.info/backref.html
评论
[^\1]
.
[^\1]
.
("|').*?\1
"foo\"
"foo \" bar"
[^\1]
(?!\1).
(["'])(?:\\.|(?!\1).)*+\1
+
以前没有涉及的一个选项是:
- 反转字符串。
- 对反转的字符串执行匹配。
- 重新反转匹配的字符串。
这还有一个额外的好处,即能够正确匹配转义的打开标签。
假设您有以下字符串; 在这里,不应该匹配,应该匹配。
最重要的是,应该匹配,不应该匹配。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"']
好的,现在来解释正则表达式。 这是正则表达式可以很容易地分成三部分。如下:
# 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
我遇到了类似的问题,试图删除可能会干扰某些文件解析的带引号的字符串。
我最终得到了一个两步解决方案,它击败了你能想到的任何复杂的正则表达式:
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
更易于阅读,可能更有效率。
如果你的IDE是IntelliJ Idea,你可以忘记所有这些麻烦,把你的正则表达式存储到一个字符串变量中,当你把它复制粘贴到双引号中时,它会自动变成一个正则表达式可接受的格式。
Java 中的示例:
String s = "\"en_usa\":[^\\,\\}]+";
现在,您可以在正则表达式或任何地方使用此变量。
(?<="|')(?:[^"\\]|\\.)*(?="|')
“这是个大问题” 比赛结果: 这是个大问题
("|')(?:[^"\\]|\\.)*("|')
“这是个大问题” 比赛结果: “这是个大问题”
评论