Notepad++ regex to move a line with certain string after a line with another string
-
Hi,
I’m looking for solution with current challenge.
Current XML file:<something>
<tag1>a<tag1>
<tag2>b<tag2>
<tag3>c<tag3>
</something>I would like a regex search and replace for all opened files in notepad (Replace All in All Opened Documents button).
Goal is to move line containing certain string, say <tag3> a few lines up, right after the line containing string <something>. Note the number of tags <tag1>, <tag2> etc. varies in different files, so regex to move line containing <tag3> 2 lines up wouldn’t work, but would also be great to know how to achieve that.
Wanted result:
<something>
<tag3>c<tag3>
<tag1>a<tag1>
<tag2>b<tag2>
</something>I’ve been using Notepad++ for all kinds of tasks, but can’t figure this one out, any help would be gratefully appreciated. Thank you
-
So a potential problem with “generalizing” your problem for posting is that you make it too general and it doesn’t work for your real use case.
Given that, I think this transforms your generalized example:
Find:
(<something>\R)(?s)(.*?)(<tag3>.*?<tag3>\R)
Replace:${1}${3}${2}
Search mode: regular expression -
@alan-kilborn
Thank you for your time and provided solution.You are right it works on provided example, but not on XML I’m trying to change.
I understand the general idea and played around with the regex, but don’t know why it doesn’t work jet. Tried to simplify it for easier understanding and so that it’s applicable to many situations.
I removed some clutter at start of xml, what I’m trying to do is for example move line with tag dcterms:created after the line dc:rights among other moves.
My guesstimate is that it doesn’t work because of xml structure, indents or something else.
<blablabla> <edm:WebResource rdf:about="link.html> <dcterms:extent>17976 KB</dcterms:extent> <dc:rights>Use of this resource is governed by the terms and conditions of the Creative Commons CC BY License</dc:rights> <edm:rights rdf:resource="http://creativecommons.org/publicdomain/mark/1.0/"/> <dc:format>PDF</dc:format> <dcterms:created>30.3.2015</dcterms:created> </edm:WebResource>
-
@alan-kilborn Replaced (<dc:rights>Use of this resource is governed by the terms and conditions of the Creative Commons CC BY License</dc:rights>\R)(?s)(.*?)(<dcterms:created>.*?</dcterms:created>\R) with ${1}${3}${2} And it worked. Can the regex be configured so that you don't have to write the whole exact line just a part of it. My logic would be something like: (*<dc:rights>*\R)(?s)(.*?)(<dcterms:created>.*?</dcterms:created>\R) but as expected it doesn't work that way. (<dc:rights>*</dc:rights>\R)(?s)(.*?)(<dcterms:created>.*?</dcterms:created>\R) Also doesn't work.
-
Looking at your expressions…they way you used
*
is "command-line"ish, not regular-expression-ish.So,
*
means “zero or more of thething
preceding”thing
is often a single character or metacharacter, or it could be something in parens…Examples:
z*
: zero or more, as many as possible, ofz
.*
: zero or more, as many as possible, of “any single character”
(abc)*
: zero or more, as many as possible, of a run ofabc
also note:
z*?
: zero or more, as few as possible, ofz
.*?
: zero or more, as few as possible, of “any single character”
(abc)*?
: zero or more, as few as possible, of a run ofabc
There’s really no way to grasp this except reading the docs and experimenting…
-
@alan-kilborn
I’m slowly achieving what I was looking for, hopefully tomorrow with a fresh start I can finish.Thank you for your help and pointers, was just trying to figure out how to adapt the regex so that the insides of first tag don’t have to be specified since they are not identical to every opened file.
This works, just some line breaks to fix. Sorry for the confusion.
(<dc:rights>.*)(?s)(.*?)(<dcterms:created>.*?</dcterms:created>\R)
-
Hello, @anonymous-guy, @alan-kilborn and All,
Let’s try a general method regarding the move of a first
<tag>
line before or after a second<tag>
line, both located in a same<tag>...........</tag>
sectionTo simplify the problem, I assume that any
<tag>..........</tag>
range, between the first and second tag included, is located in a single line ( not splitted over several lines ! )-
Let the first tag met, be called
<tag_A>
-
Let the second tag met, be called
<tag_B>
Then, we can imagine the generic regex S/R, below :
SEARCH
(?-s)(^\h*
<tag_A>.*\R)(?s)(.*)(?-s)(^\h*
<tag_B>.*\R)
REPLACE
\3\1\2
(tag_B
line is moved right before the<tag_A>
line )
REPLACE\1\3\2
(tag_B
line is moved right after the<tag_A>
line )
REPLACE\2\1\3
(tag_A
line is moved right before the<tag_B>
line )
REPLACE\2\3\1
(tag_A
line is moved right after the<tag_B>
line )
REPLACE\3\2\1
(tag_A
line and<tag>_B
line are switched )
In your case, given your INITIAL text, below :
<blablabla> <edm:WebResource rdf:about="link.html> <dcterms:extent>17976 KB</dcterms:extent> <dc:rights>Use of this resource is governed by the terms and conditions of the Creative Commons CC BY License</dc:rights> <edm:rights rdf:resource="http://creativecommons.org/publicdomain/mark/1.0/"/> <dc:format>PDF</dc:format> <dcterms:created>30.3.2015</dcterms:created> </edm:WebResource>
With the practical following regex S/R :
SEARCH
(?-s)(^\h*<dc:rights>.*\R)(?s)(.*)(?-s)(^\h*<dcterms:created>.*\R)
REPLACE
\1\3\2
We get the expected results :
<blablabla> <edm:WebResource rdf:about="link.html> <dcterms:extent>17976 KB</dcterms:extent> <dc:rights>Use of this resource is governed by the terms and conditions of the Creative Commons CC BY License</dc:rights> <dcterms:created>30.3.2015</dcterms:created> <edm:rights rdf:resource="http://creativecommons.org/publicdomain/mark/1.0/"/> <dc:format>PDF</dc:format> </edm:WebResource>
Best Regards,
guy038
-
-
@guy038 I tried applying your regex but it somehow didn’t work, probably it was something I did wrong so I used Alans regex for the original task.
Next day I also needed exactly the regex you shared and it worked perfectly without breaking any code indents, just awesome! I’ll surely use it again in near future it would be really time consuming to try to change line order manually.
Thank you so so much for taking the time and effort to share your solution and making it so clear to understand I really appreciate it.
@guy038 and @Alan-Kilborn
Thank you both for your time and solutions I’m really grateful and if anyone has a buy me coffee page or any other way I can at least symbolically show my gratitude let me know.
Have a great day ( :
-
@anonymous-guy said in Notepad++ regex to move a line with certain string after a line with another string:
I’m really grateful and if anyone has a buy me coffee page or any other way I can at least symbolically show my gratitude let me know.
I can take care of that as well: