Reputation: 24798
My text "can contain" both single 'and double"' quotes. The quotes "can also be 'nested" as you can see.
(array with 3 items)
can contain
and double"
can also be 'nested
I'm not a regex expert, far from it. I still managed to get text between double quotes like I can "grab this" text
.
preg_match_all("~\"(.*?)\"~", $text, $between);
print_r($between);
This is "A text"
(A text)This is 'A text'
(A text)This is "A 'text"
(A 'text)This is 'A "text'
(A "text)This is "A text
(Uneven quotes 1)This is 'A text
(Uneven quotes 1)This is "A "text"
(Uneven quotes 3)This is 'A 'text'
(Uneven quotes 3)This "is ' A " text'
(Intersecting)This "has "one wrong" quote
)My guess is that each character needs to be looped and checked. If it starts with a "
, it needs to step the characters to the next "
in order to wrap it in. Then I guess it's need to be reset from that position to see what the next type of quote is and to it again until the string has ended.
This answer does not work for my problem: regex match text in either single or double quote
A proof can be seen here: https://regex101.com/r/OVdomu/65/
Upvotes: 4
Views: 641
Reputation: 627545
You may use
if (preg_match_all('~(?|"([^"]*)"|\'([^\']*)\')~', $txt, $matches)) {
print_r($matches[1]);
}
See the regex demo and the PHP demo.
A variation that supports escaped quotes, too:
'~(?|"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')~s'
See this regex demo.
The (?|"([^"]*)"|\'([^\']*)\')
is a branch reset group matching either "
, then any 0+ chars other than "
and then a "
or a '
, then any 0+ chars other than '
and then '
, while capturing into Group 1 all the contents between the matching quotation marks.
Upvotes: 1