A simple search and replace
-
Good afternoon everyone and thanks in advance. First time around in Notepad ++ and having a challenge with a straightforward search and replace. I have a string that contains a keyword, a space, a double quote, some random text and a second double quote. I need to change the double quotes to single quotes and preserve the keyword and the enclosed text. For example, I might have keyword like and the line of text
When OrderType like “%Sandwich%” then OrderType||" $"||OrderAmount
I’ve tried a find of
like “(.*)”(. *)
{No space between the period and the asterisk within the second parenthesis. Wasn’t displaying correctly without it}and a replace with
like ‘${1}’${2}
but that’s returning
When OrderType like ‘%Sandwich%" then OrderType||" $’||OrderAmount
Changing the first and last double quote where I was trying to replace the two wrapping %Sandwich.
Many, many thanks in advance.
-
@Steven-Perry said in A simple search and replace:
“(.*)”(. *)
Your
*
is greedy. You likely need lazy (use*?
), read Rexegg.com.Terry
-
@Terry-R Thank you VERY much. Your help was greatly appreciated.
-
A regex that matches a quoted string could be pretty complicated, and it depends a lot on how literal
"
characters inside the string are handled.If you know for certain that all the strings you need to match do not contain literal
"
characters, you can use"[^\r\n"]*"
.If literal
"
characters are represented by""
(for example,The "big" dog
would become"The ""big"" dog"
), you can use the regex"(?:""|[^\r\n"])*"
, although that could break if the file contains any unterminated strings.If literal quote characters are represented by
\"
(as in JSON and most C-like programming languages), the regex"(?:\\\\|\\"|[^\r\n"\\])*"
will work, although that will also break if your file contains any unterminated strings.In both of the cases described above where the string could contain literal quote characters, it is literally impossible (AFAIK) to construct a regular expression that correctly ignores unterminated strings.
-
@Mark-Olson said in A simple search and replace:
In both of the cases described above where the string could contain literal quote characters, it is literally impossible (AFAIK) to construct a regular expression that correctly ignores unterminated strings.
I was intrigued by this, but I guess I’m having some trouble figuring out what would constitute correctly ignoring unterminated strings.
In the case of the doubled quote method, if you mean that a string can’t end on the first of two adjacent quotes when no further quote exists on the line, I think this:
"(?:""|[^\r\n"])*+(?:"|(*SKIP)(*FAIL))
would work (but I might have missed something).I’m missing how unterminated strings mess up the backslash escape method, but the expression given fails for strings that include any escapes other than backslashes or quotes, such as
\n
. I think this:
"(?:\\[^\r\n]|[^\r\n"\\])*"
would work, but I haven’t tested. -
@Coises said in A simple search and replace:
In the case of the doubled quote method, if you mean that a string can’t end on the first of two adjacent quotes when no further quote exists on the line, I think this:
“(?:”“|[^\r\n”])*+(?:"|(*SKIP)(*FAIL))
would work (but I might have missed something).Yes, that would work. Clever use of
(*SKIP)(*FAIL)
and the greedy*+
.I’m missing how unterminated strings mess up the backslash escape method, but the expression given fails for strings that include any escapes other than backslashes or quotes, such as \n. I think this:
“(?:\[^\r\n]|[^\r\n”\])*"I’m honestly surprised that I didn’t come up with this myself. That does appear to work.
-
Hello, @terry-r, @steven-Perry, @mark-olson, @coises, and All,
@steven-Perry, if your double quotes, which need to be changed as simple quotes, are ALWAYS followed or preceded with the
%
character, you could just use this simple regex S/R :-
SEARCH
(?<=%)"|"(?=%)
-
REPLACE
'
Now, @mark-olson and @coises, although I ( finally ! ) managed to understand your different regexes, I would like to simplify the problem :
-
First, we want to search any string which is embedded in two double quotes, exactly
-
Secondly, the string may contain :
-
Any standard char, different from
"
, in a lazy configuration -
Any standard char in a greedy configuration
-
Any escaped character, including the string
\"
, whatever the greedy or lazy form is used
-
To my mind, all these statements can be solved with the two following regexes :
-
Regex A :
(?-s)"(?:\\.|.)+"
-
Regex B :
(?-s)"(?:\\.|.)+?"
For example, Let’s consider the simple text :
"This\"\""is a"\"dummy" text"to see\how \'these"regexes"work !
Against this text, these two regexes return :
<--------------------------1-----------------------------> Regex A ( 1 occ. ) "This\"\""is a"\"dummy" text"to see\how \'these"regexes"work ! <----1---> <---2---> <---------3---------> Regex B ( 3 occ. )
May be, @mark-olson and @coises, I simplified the problem too much ! Just tell me what I’m missing :-))
Best Regards,
guy038
Note that the alternate solutions :
(?-s)"(?:\\.|(?!").)+"
(?-s)"(?:\\.|(?!").)+?"
Are rather useless, as identical to the regex B. Easy to understand why !
-
-
@guy038 said in A simple search and replace:
To my mind, all these statements can be solved with the two following regexes :
Regex A : (?-s)"(?:\\.|.)+" Regex B : (?-s)"(?:\\.|.)+?"
I would use Regex B with a slight modification; the
+?
should be a*?
to correctly handle the empty string""
.Thus, I think the simplest regex we can use for this task is probably
(?-s)"(?:\\.|.)*?"
There is one important caveat here: these regexes for recognizing JSON strings will break if you start the search in the middle of a string.
For example, if you have this text
"foo" "bar" "from\r\n\t[\"\\\"here\\\"\", \"to\", \"here\" is all one string]"
the best regex,
(?-s)"(?:\\.|.)*?"
, will correctly identify exactly three strings in the file if you start the search at the beginning of the file.But if you start with the caret after the word
from
on the second line, you will incorrectly identify"\\\"here\\\"\", \"to\", \"here\" is all one string]"
as being a valid string.