What regex expression will match all characters except ", except when it is \"? - regex

I'm trying to parse an apache log, and I'm having problems with the right syntax for the referer because it is a string inside " (double-quotes), that can also have \" inside it.
"([^"]*)" doesn't work when there is a \" in the string.
How do I start at the 1st double-quote, then take all characters that are not double-quotes, unless it's \", in which case I include it, and keep going?

You could use this:
"((?:[^"]|\\")*)"
It will match zero or more of any character other than a double-quote or a slash-double-quote pair, all surrounded by double-quotes.

Could there be other escapes in the string, for example "hello \\"? In that case, you need a more general approach:
"((?:\\.|[^"\\])*)"

How about this? A negative-lookbehind to exclude a \ before the closing "
"(.+?)(?<!\\)"

This will match two quotes with any number of escaped quotes in-between:
"\([^"]\|\\"\)*"
First it looks for a quote. Next it searches for zero to infinity of the following:
a non-quote character
a quote character preceded by a backslash

Related

Regex in Flutter to find double quotes enclosed words and escaped single quotes

I am using this Regex in my Flutter App to find words enclosed by single-quotes that end with a .tr:
r"'[^'\\]*(?:\\.[^'\\]*)*'\s*\.tr\b"
Now I need another expression that is almost the same but looks for words enclosed by dobule-quotes, ending with .tr and might contain escaped single-quotes.
I tried simply changing the single quotes to double quotes from the first expression, but Flutter is giving me errors... I need to escaped some characters but I can not make it work. Any idea?
An edge case it should match is:
"Hello, I\'m Chris".tr
You may use this regex for double quoted text that can have any escaped character followed by .tr and word boundary:
r""""[^"\\]*(?:\\.[^"\\]*)*"\s*\.tr\b"""
RegEx Demo
you need to use \ before every " in your RegExp's source, try this:
RegExp regExp = new RegExp(r'\"[^\"\\]*(?:\\.[^\"\\]*)*\"\s*\.tr\b');
print("${regExp.hasMatch('"Hello, I\'m Chris".tr')}"); // result = true

How to exclude part of string using regex and change add this part and the and of string?

I've got a little problem with regex.
I got few strings in one file looking like this:
TEST.SYSCOP01.D%%ODATE
TEST.SYSCOP02.D%%ODATE
TEST.SYSCOP03.D%%ODATE
...
What I need is to define correct regex and change those string name for:
TEST.D%%ODATE.SYSCOP.#01
TEST.D%%ODATE.SYSCOP.#02
TEST.D%%ODATE.SYSCOP.#03
Actually, I got my regex:
r".SYSCOP[0-9]{2}.D%%ODATE" - for finding this in file
But how should look like the changing regex? I need to have the numbers from a string at the and of new string name.
.D%%ODATE.SYSCOP.# - this is just string, no regex and It didn't work
Any idea?
Find: (SYSCOP)(\d+)\.(D%%ODATE)
Replace: $3.$1.#$2 or \3.\1.#\2 for Python
Demo
You may use capturing groups with backreferences in the replacement part:
s = re.sub(r'(\.SYSCOP)([0-9]{2})(\.D%%ODATE)', r'\3\1.#\2', s)
See the regex demo
Each \X in the replacement pattern refers to the Nth parentheses in the pattern, thus, you may rearrange the match value as per your needs.
Note that . must be escaped to match a literal dot.
Please mind the raw string literal, the r prefix before the string literals helps you avoid excessive backslashes. '\3\1.#\2' is not the same as r'\3\1.#\2', you may print the string literals and see for yourself. In short, inside raw string literals, string escape sequences like \a, \f, \n or \r are not recognized, and the backslash is treated as a literal backslash, just the one that is used to build regex escape sequences (note that r'\n' and '\n' both match a newline since the first one is a regex escape sequence matching a newline and the second is a literal LF symbol.)

Regex replace escaped characters

I would like to define a regex pattern which replaces escaped characters with the corresponding value.
For example the string
xy\tz\\x
Should be converted to
xy{tab}z\x
The problem is how to handle things like
xy\\\\\t
this string should become
xy\\{tab}
I don't know how to create a pattern which matches only odd backslashes.
This isn't something that can be accomplished using a single pattern. To start, strip out collections of backslashes:
s/\\\\/\\/g
This replaces two backslashes with a single one.
Then you can just apply one pattern per escaped character:
s/\\t/\t/g
The trick here is to escape the backslash you want to replace. What this'll do is replace the literal string "\t" with a tab character.

Regex for matching literal strings

I'm trying to write a regular expression which will match a string. For simplicity, I'm only concerned with double quote (") strings for the moment.
So far I have this: "\"[^\"]*\""
This works for most strings but fails when there is an escaped double quote such as this:
"a string \" with an escaped quote"
In this case, it only matches up to the escaped quote.
I've tried several things to allow an escaped quote but so far I've been unsuccessful, can anyone give me a hand?
I've managed to solve it myself:
"\"(\\.|[^\"\\])*\""
Try this:
"[^"\\\r\n]*(?:\\.[^"\\\r\n]*)*"
If you want a multi-line escaped string you can use:
"[^"\\]*(?:\\.[^"\\]*)*"
You need a negative lookbehind. Check if this works?
"\"[^\"]*(?<!\\)"
(?<!\\)" is supposed to match " that's not followed by \.
Try:
"((\\")|[^"(\\")])+"
From Regular Expression Library.
Usually you want to accept escaped anything.
" [^"\\]* (?: \\. [^"\\]* )* " would be the fastest.
"[^"\\]*(?:\\.[^"\\]*)*" compressed.
POSIX does not, AFAIK, support lookaround - without it, there is really no way to do this with just regular expressions. However, according to a POSIX emulator I have (no access to a native environment or library), This might get you close, in certain cases:
"[^\"]*"|"[^\]*\\|\\[^\"]*[\"]
it will capture the part before and the part after the escaped quote... with this source string (ignore the line breaks, an imagine it's all in one string):
I want to match "this text" and "This text, where there is an escaped
slash (\\), and an \"escaped quote\" (\")", but I also want to handle\\ escaped
back-slashes, as in "this text, with a \\ backslash: \\" -- with a little
text behind it!
it will capture these groups:
"this text" -- simple, quoted string
"This text, where there is an escaped slash (\ -- part 1 of quoted string
\), and an \ -- part 2
"escaped quote\ -- part 3
" (\ -- part 4
")" -- part 5, and ends with a quote
\\ -- not part of a quoted string
"this text, with a \ -- part 1 of quoted string
\ backslash: \ -- part 2
\" -- part 3, and ends with a quote
With further analysis you can combine them, as appropriate:
If the group starts and ends with a ", then it is fine on its own
If the group starts with a ", and ends with a \, then it needs to be IMMEDIATELY followed by another match group that either ends with a quote character itself, or recursively continues to be IMMEDIATELY followed by another match group
If the group does not immediately follow another match, it is not part of a quoted string
I think that's all the analysis that you need - but make sure to test it!!!
Let me know if this idea helps!
EDIT:
Additional note: just to be clear, for this to work all quotes in the entire source string must be escaped if they are not to be used as delimiters, and backslashes must be escaped everywhere as well

How can I match double-quoted strings with escaped double-quote characters?

I need a Perl regular expression to match a string. I'm assuming only double-quoted strings, that a \" is a literal quote character and NOT the end of the string, and that a \ is a literal backslash character and should not escape a quote character. If it's not clear, some examples:
"\"" # string is 1 character long, contains dobule quote
"\\" # string is 1 character long, contains backslash
"\\\"" # string is 2 characters long, contains backslash and double quote
"\\\\" # string is 2 characters long, contains two backslashes
I need a regular expression that can recognize all 4 of these possibilities, and all other simple variations on those possibilities, as valid strings. What I have now is:
/".*[^\\]"/
But that's not right - it won't match any of those except the first one. Can anyone give me a push in the right direction on how to handle this?
/"(?:[^\\"]|\\.)*"/
This is almost the same as Cal's answer, but has the advantage of matching strings containing escape codes such as \n.
The ?: characters are there to prevent the contained expression being saved as a backreference, but they can be removed.
NOTE: as pointed out by Louis Semprini, this is limited to 32kb texts due a recursion limit built into Perl's regex engine (that unfortunately silently returns a failure when hit, instead of crashing loudly).
How about this?
/"([^\\"]|\\\\|\\")*"/
matches zero or more characters that aren't slashes or quotes OR two slashes OR a slash then a quote
A generic solution(matching all backslashed characters):
/ \A " # Start of string and opening quote
(?: # Start group
[^\\"] # Anything but a backslash or a quote
| # or
\\. # Backslash and anything
)* # End of group
" \z # Closing quote and end of string
/xms
See Text::Balanced. It's better than reinvent wheel. Use gen_delimited_pat to see result pattern and learn form it.
RegExp::Common is another useful tool to be aware of. It contains regexps for many common cases, included quoted strings:
use Regexp::Common;
my $str = '" this is a \" quoted string"';
if ($str =~ $RE{quoted}) {
# do something
}
Here's a very simple way:
/"(?:\\?.)*?"/
Just remember if you're embedding such a regex in a string to double the backslashes.
Try this piece of code : (\".+")