【问题标题】:How to match string in single or double quoted using regex如何使用正则表达式匹配单引号或双引号中的字符串
【发布时间】:2016-10-06 12:02:12
【问题描述】:

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

translate("some text here")

translate('some text here')

我已经做到了:

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

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

【问题讨论】:

    标签: regex quotes


    【解决方案1】:

    你可以去:

    translate\( # translate( literally
    (['"])      # capture a single/double quote to group 1
    .+?         # match anything except a newline lazily
    \1          # 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
                \1          # up to the formerly captured quote
                \)          # and a closing parenthesis
             ~x';
    
    if (preg_match($regex, $string)) {
        // do sth. here
    }
    ?>
    

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


    在 cmets 中出现了关于您不能说除了第一个捕获的组之外的任何内容的讨论。嗯,是的,你可以(感谢奥巴马在这里),该技术称为tempered greedy token,可以通过环视来实现。考虑以下代码:
    translate\(
    (['"])
    (?:(?!\1).)*
    \1
    \)
    

    它会打开一个具有否定前瞻的非捕获组,以确保不匹配以前捕获的组(本示例中的引用)。
    这会消除 translate("a"b"c"d") 之类的匹配项(请参阅 a demo here)。


    match all given examples 的最终表达式是:
    translate\(
    (['"])
    (?:
       .*?(?=\1\))
    )
    \1
    \)
    

    【讨论】:

    • 谢谢大家!我不知道什么是正确的方法,我试试看。
    • you do not need to escape the quotes in square brackets 实际上你必须这样做,否则你的 php 解析器将会死掉。
    • @vp_arth:你是对的,你可以看到我在我的代码示例中做到了。我的意思是你不需要转义 both 的引号。
    • 它仍然与 translate("a"b"c"d") 有错误匹配。而且我的代码在这里也失败了:(这是因为.匹配引号,但是没有办法声明[^\1]字符类
    • 所以,我可以用这个来修改我的答案。你的一个现在在正确转义的引号上失败了,比如translate("a\"b\"c\"d") ;)
    【解决方案2】:
    @translate\(
    ([\'"])      # capture quote char
    ((?:
      (?!\1).    # not a quote
    |            # or
      \\\1       # escaped one
    )* # 
    [^\\\\]?)\1    # 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")
    

    【讨论】:

    • 对你的投了赞成票,但在底部看到我的更新答案(欢迎新挑战:)
    【解决方案3】:

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

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

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

    【讨论】:

    • translate("some text here') 你还必须在 php 字符串中转义引号。
    • 它会找到两个匹配项 - 如果我有 - translate('text') 和 translate("text")?
    • 是的,但正如@vp_arth 所说,它也将匹配translate("some text here') 我将对其进行编辑以使其正常工作
    • 有办法,但不是很聪明-> if(preg_match ('/translate("(.*?)")*/', $line, $m) || preg_match ("/translate('(.*?)')*/", $line, $m)) {
    • 在 js 中效果很好:/([\"'])(?:\\\1|.)*?\1/。可能有人可以将其翻译成 php 吗?
    猜你喜欢
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多