5

I've got something like this:

$class = 'class="cl"' . " style=" . '"color:black,' . "background:red;" . '"';

Is there any simple way by regex to format this code to " ' ' " style? I mean this:

$class = "class='cl'" . " style=" . "'color:black," . "background:red;" . "'";

I tried this regex:

'(?!(([^"]"){2})[^"]*$)

But this replaces outer single quotes ' only. How can I also replace inner double quotes by single quotes?

trincot
  • 317,000
  • 35
  • 244
  • 286
newtonrus
  • 105
  • 8

3 Answers3

3

You could do this in three steps, where only the first one needs a regular expression:

  1. Replace each outer quote (whatever kind -- single or double) with a non-used character (e.g. µ), a pair at a time:

    Find: ('|")(((?!\1).)*).
    Repl: µ\2µ

  2. Replace each remaining double quote with a single quote, since by consequence of step 1 they are inner:

    Find: "
    Repl: '

  3. Replace each occurrence of the special character (of step 1) with a double quote

    Find: µ
    Repl: "

Evidently the first (and only) regular expression does the major magic: it captures the first quote it finds (single or double) and then captures characters up to the next occurrence of the same kind of quote (using the \1 back-reference in a negative condition and eventually matching that second occurrence with .). The condition for this to work is that all outer quotes come in pairs.

When you launch the first replacement, make sure that your caret is at the very start of the text so it starts outside of any quote pair.

NB: PHP (which you seem to use, but it's true also in several other languages) allows quotes with string literals to be escaped with backslashes. The task would become a bit more complex if such escapes were present in your input, but it is possible.

trincot
  • 317,000
  • 35
  • 244
  • 286
2

My own solution. There are 4 regex for Notepad++.

1. Find all double-quotes (") inside two single-quotes (') and replace them with tilde (~):

RegEx: (?:\G(?!^)|([^']*(?:'[^'"]*'[^']*)*'))[^"']*\K"([^"']*+(?:'(?1)|$))?
Replacement: ~$2

2. Find all single-quotes (') not surrounded by two double-quotes (") and replace them with backquote (`):

RegEx: '(?=(?:[^"]*"[^"]*")*[^"]*$)
Replacement: `

3. Find all tildes (~) inside two backquotes (`) and replace them with single-quote ('):

RegEx: (?:\G(?!^)|([^`]*(?:`[^`~]*`[^`]*)*`))[^~`]*\K~([^~`]*+(?:`(?1)|$))?
Replacement: '$2

4. And last step, all tildes (~) and backquotes (`) to replace with double-quotes ("):

RegEx: ~|`
Replacement: "

Tildes and backquotes should not be appeared in code before first step. Thanks to link1 and link2

newtonrus
  • 105
  • 8
0

Notepad++ uses the regex engine from the Boost.Regex C++ lib.
So one can use Conditional Replacement in the replace string.

Using that trick then only 1 regex replacement can do the job.

In Notepad++

Find what:

(?:"[^"]*"\s*[.;]\K)|(?:(?:(')|("))(?=[^.;]*?[.;]))

About the regex, first it matches the parts surrounded by double quotes, and removes those from the match results via the \K. The remaining quotes are then captured.

Replace with:

(?1")(?2')

Search mode :

Regular expression

Example:

This sample string:

$class = 'change="this"' . 'change="this" change="this"' . 'change"this"' . '"change:this,' . " keep=this" . " keep:this;" . "dontchange='this'" . '"' . '"change_me"';

Changes to:

$class = "change='this'" . "change='this' change='this'" . "change'this'" . "'change:this," . " keep=this" . " keep:this;" . "dontchange='this'" . "'" . "'change_me'";
LukStorms
  • 28,916
  • 5
  • 31
  • 45
  • LukStorms, thanks for your one step solution! :) ,but it does not work if there are more than 2 inner double-quotes. Try for example this: 'xxx="yyy"' 'xxx="yyy" xxx="yyy"' 'xxx="yyy"' – newtonrus Jun 09 '18 at 10:13
  • "xxx='yyy'" 'xxx="yyy" xxx="yyy"" "xxx="yyy"' first string is ok, second one is not ok, third not ok also because of second string. But I agree and I think there is a solution with conditional replacement. – newtonrus Jun 09 '18 at 10:19
  • @newtonrus Urgh, multiple groups with double quotes between single quotes. A pure regex replacement solution is kinda problematic with things like nesting and the like. Anyway, I've changed my solution a tad. Now it'll also take care of those. – LukStorms Jun 09 '18 at 13:22
  • LukStorms, your new regex is more correct, but still there are mistakes. for example correct string like: "dontchange='this'" your regex is changing too: 'dontchange="this"" – newtonrus Jun 09 '18 at 18:08
  • That's no longer changing in the current version. – LukStorms Jun 10 '18 at 15:37
  • LukStorms, I've tested your new version and found probably only one err: it does not change '"change_me"' :) – newtonrus Jun 11 '18 at 12:21
  • @newtonrus Lol, this kinda reminds me of that esoteric programming language [Unreadable](https://esolangs.org/wiki/Unreadable). The previous version was looking for a dot after it. The new version looks for a `.` or a `;` – LukStorms Jun 11 '18 at 18:49