Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper Lua pattern for quoted text?

I've been playing with this for an hour or tow and have found myself at a road block with the Lua pattern matching utilities. I am attempting to match all quoted text in a string and replace it if needed.

The pattern I have come up with so far is: (\?[\"\'])(.-)%1

This works in some cases but, not all cases:

Working: "This \"is a\" string of \"text to\" test with"

Not Working: "T\\\"his \"is\' a\" string\" of\' text\" to \"test\" wit\\\"h"

In the not working example I would like it to match to (I made a function that gets the matches I desire, I'm just looking for a pattern to use with gsub and curious if a lua pattern can do this):

 string
 a" string" of
is' a" string" of' text
test
his "is' a" string" of' text" to "test" wit

I'm going to continue to use my function instead for the time being, but am curious if there is a pattern I could/should be using and i'm just missing something with patterns.

(a few edits b/c I forgot about stackoverflows formating) (another edit to make a non-html example since it was leading to assumptions that I was attempting to parse html)

like image 995
Wolftousen Avatar asked Nov 30 '10 18:11

Wolftousen


2 Answers

Trying to match escaped, quoted text using regular expressions is like trying to remove the daisies (and only the daises) from a field using a lawnmower.

I made a function that gets the matches I desire

This is the correct move.

I'm curious if a lua pattern can do this

From a practical point of view, even if a pattern can do this, you don't want to. From a theoretical point of view, you are trying to find a double quote that is preceded by an even number of backslashes. This is definitely a regular language, and the regular expression you want would be something like the following (Lua quoting conventions)

[[[^\](\\)*"(.-[^\](\\)*)"]]

And the quoted string would be result #2. But Lua patterns are not full regular expressions; in particular, you cannot put a * after a parenthesized pattern. So my guess is that this problem cannot be solved using Lua patterns, but since Lua patterns are not a standard thing in automata theory, I'm not aware of any body of proof technique that you could use to prove it.

like image 169
Norman Ramsey Avatar answered Nov 15 '22 08:11

Norman Ramsey


The issue with escaped quotes is that, in general, if there's an odd number of backslashes before the quote, then it's escaped, and if there's an even number, it's not. I do not believe that Lua pattern-matching is powerful enough to represent this condition, so if you need to parse text like this, then you should seek another way. Perhaps you can iterate through the string and parse it, or you could find each quote in turn and read backwards, counting the backslashes until you find a non-backslash character (or the beginning of the string).

If you absolutely must use patterns for some reason, you could try doing this in a multi-step process. First, gsub for all occurrences of two backslashes in a row, and replace them with some sentinel value. This must be a value that does not already occur in the string. You could try something like "\001" if you know this string doesn't contain non-printable characters. Anyway, once you've replaced all sequences of two backslashes in a row, any backslashes left are escaping the following character. Now you can apply your original pattern, and then finally you can replace all instances of your sentinel value with two backslashes again.

like image 41
Lily Ballard Avatar answered Nov 15 '22 08:11

Lily Ballard