I\'m trying to write a regex that matches strings as the following:
translate(\"some text here\")
and
translate(\'some text here\'
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.
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 ?).
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).
translate\(
(['"])
(?:
.*?(?=\1\))
)
\1
\)
@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")
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.