How to match string in single or double quoted using regex

前端 未结 3 1231
一生所求
一生所求 2021-01-18 16:48

I\'m trying to write a regex that matches strings as the following:

translate(\"some text here\")

and

translate(\'some text here\'

相关标签:
3条回答
  • 2021-01-18 17:14

    You could go for:

    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
    

    See a demo for this approach on regex101.com.


    In PHP this would be:

    <?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
    }
    ?>
    

    Note that you do not need to escape both of the quotes in square brackets ([]), I have only done it for the Stackoverflow prettifier.
    Bear in mind though, that this is rather error-prone (what about whitespaces, escaped quotes ?).


    In the comments the discussion came up that you cannot say anything BUT the first captured group. Well, yes, you can (thanks to Obama here), the technique is called a tempered greedy token which can be achieved via lookarounds. Consider the following code:

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

    It opens a non-capturing group with a negative lookahead that makes sure not to match the formerly captured group (a quote in this example).
    This eradicates matches like translate("a"b"c"d") (see a demo here).


    The final expression to match all given examples is:

    translate\(
    (['"])
    (?:
       .*?(?=\1\))
    )
    \1
    \)
    
    0 讨论(0)
  • 2021-01-18 17:23
    @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")
    
    0 讨论(0)
  • 2021-01-18 17:40

    You can alternate expression components using the pipe (|) like this:

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

    Edit: previous also matched translate("some text here'). This should work but you will have to escape the quotes in some languages.

    0 讨论(0)
提交回复
热议问题