如何使用正则表达式匹配单引号或双引号中的字符串

How to match string in single or double quoted using regex

我正在尝试编写一个匹配字符串的正则表达式,如下所示:

translate("some text here")

translate('some text here')

我已经做到了:

preg_match ('/translate\("(.*?)"\)*/', $line, $m) 

但是如果有单引号而不是双引号怎么加。它应该匹配为单引号,双引号。

您可以像这样使用竖线 (|) 替换表达式组件:

preg_match ('/translate(\("(.*?)"\)|\(\'(.*?)\'\))/', $line, $m)

编辑:之前也匹配 translate("some text here')。这应该可行,但您必须转义某些语言的引号。

你可以选择:

translate\( # translate( literally
(['"])      # capture a single/double quote to group 1
.+?         # match anything except a newline lazily
          # up to the formerly captured quote
\)          # and a closing parenthesis

查看 this approach on regex101.com 的演示。


PHP 中,这将是:

<?php

$regex = '~
            translate\( # translate( literally
            ([\'"])     # capture a single/double quote to group 1
            .+?         # match anything except a newline lazily
                      # up to the formerly captured quote
            \)          # and a closing parenthesis
         ~x';

if (preg_match($regex, $string)) {
    // do sth. here
}
?>

注意您不需要转义方括号中的两个引号 ([]),我只为 Whosebug 美化器做过。
但请记住,这很容易出错(空格、转义引号怎么样?)。


在评论中讨论了你不能说 除了第一个捕获的组 之外的任何内容。好吧,是的,你可以(感谢 Obama 在这里),这项技术被称为 tempered greedy token,可以通过环顾四周来实现。考虑以下代码:

translate\(
(['"])
(?:(?!).)*

\)

它打开一个带有负前瞻的非捕获组,确保不匹配以前捕获的组(本例中的引号)。
这消除了像 translate("a"b"c"d") 这样的匹配(参见 a demo here)。


match all given examples 的最终表达式是:

translate\(
(['"])
(?:
   .*?(?=\))
)

\)
@translate\(
([\'"])      # capture quote char
((?:
  (?!).    # not a quote
|            # or
  \       # escaped one
)* # 
[^\\]?)    # match unescaped last quote char
\)@gx

Fiddle:

ok: translate("some text here")
ok: translate('some text here')
ok: translate('"some text here..."')
ok: translate("a\"b\"c\"d")
ok: translate("")
no: translate("a\"b"c\"d")