Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regexp-replace: Multiple replacements within a match

I'm converting our MVC3 project to use T4MVC. And I would like to replace java-script includes to work with T4MVC as well. So I need to replace

"~/Scripts/DataTables/TableTools/TableTools.min.js"
"~/Scripts/jquery-ui-1.8.24.min.js"

Into

Scripts.DataTables.TableTools.TableTools_min_js
Scripts.jquery_ui_1_8_24_min_js

I'm using Notepad++ as a regexp tool at the moment, and it is using POSIX regexps. I can find script name and replace it with these regexps:

Find: \("~/Scripts/(.*)"\)

Replace with \(Scripts.\1\)

But I can't figure out how do I replace dots and dashes in the file names into underscores and replace forward slashes into dots.

I can check that js-filename have dot or dash in a name with this

 \("~/Scripts/(?=\.*)(?=\-*).*"\)

But how do I replace groups within a group?

Need to have non-greedy replacement within group, and have these replacements going in an order, so forward slashes converted into a dot will not be converted to underscore afterwards.

This is a non-critical problem, I've already done all the replacements manually, but I thought I'm good with regexp, so this problem bugs me!!

p.s. preferred tool is Notepad++, but any POSIX regexp solution would do -)

p.p.s. Here you can get a sample of stuff to be replaced And here is the the target text

like image 527
trailmax Avatar asked Oct 08 '12 12:10

trailmax


People also ask

How do I replace multiple items in a string?

sub() and re. subn() to replace multiple substrings in a string. sub() - It replaces the contents of a string based on patterns. It takes a pattern or a string as the first argument.

How do you replace multiple values?

Find and replace multiple values with nested SUBSTITUTE The easiest way to find and replace multiple entries in Excel is by using the SUBSTITUTE function. The formula's logic is very simple: you write a few individual functions to replace an old value with a new one.

How do you replace all occurrences of a regex pattern in a string?

sub() method will replace all pattern occurrences in the target string. By setting the count=1 inside a re. sub() we can replace only the first occurrence of a pattern in the target string with another string. Set the count value to the number of replacements you want to perform.

What is $1 in regex replace?

For example, the replacement pattern $1 indicates that the matched substring is to be replaced by the first captured group.


2 Answers

I would just use a site like RegexHero

  1. You can past the code into the target string box, then place (?<=(~/Script).*)[.-](?=(.*"[)]")) into the Regular Expression box, with _ in the Replacement String box.

  2. Once the replace is done, click on Final String at the bottom, and select Move to target string and start a new expression.

  3. From there, Paste (?<=(<script).*)("~/)(?=(.*[)]" ))|(?<=(Url.).*)(")(?=(.*(\)" ))) into the Regular Expression box and leave the Replacement String box empty.

  4. Once the replace is done, click on Final String at the bottom, and select Move to target string and start a new expression.

  5. From there paste (?<=(Script).*)[/](?=(.*[)]")) into the Regular Expression box and . into the Replacement String box.

After that, the Final String box will have what you are looking for. I'm not sure the upper limits of how much text you can parse, but it could be broken up if that's an issue. I'm sure there might be better ways to do it, but this tends to be the way I go about things like this. One reason I like this site, is because I don't have to install anything, so I can do it anywhere quickly.

Edit 1: Per the comments, I have moved step 3 to Step 5 and added new steps 3 and 4. I had to do it this way, because new Step 5 would have replaced the / in "~/Scripts with a ., breaking the removal of "~/. I also had to change Step 5's code to account for the changed beginning of Script

like image 53
Nick Avatar answered Sep 28 '22 10:09

Nick


Here is a vanilla Notepad++ solution, but it's certainly not the most elegant one. I managed to do the transformation with several passes over the file.

First pass

Replace . and - with _.

Find: ("~/Scripts[^"]*?)[.-]

Replace With: \1_

Unfortunately, I could not find a way to match only the . or -, because it would require a lookbehind, which is apparently not supported by Notepad++. Due to this, every time you execute the replacement only the first . or - in a script name will be replaced (because matches cannot overlap). Hence, you have to run this replacement multiple times until no more replacements are done (in your example input, that would be 8 times).

Second pass

Replace / with ..

Find: ("~/Scripts[^"]*?)/

Replace with: \1.

This is basically the same thing as the first pass, just with different characters (you will have to this 3 times for the example file). Doing the passes in this order ensures that no slashes will end up as underscores.

Third pass

Remove the surrounding characters.

Find: "~/(Scripts[^"]*?)"

Replace with: \1

This will now match all the script names that are still surrounded by "~/ and ", capturing what is in between and just outputting that.

Note that by including those surrounding characters in the find patterns of the first two passes, you can avoid converting the . in strings that are already of the new format.

As I said this is not the most convenient way to do it. Especially, since passes one and two have to be executed manually multiple times. But it would still save a lot of time for large files, and I cannot think of a way to get all of them - only in the correct strings - in one pass, without lookbehind capabilities. Of course, I would very much welcome suggestions to improve this solution :). I hope I could at least give you (and anyone with a similar problem) a starting point.

like image 44
Martin Ender Avatar answered Sep 28 '22 09:09

Martin Ender