Replace between two line
-
Hello
Im in trouble for hours. I want to replace everything between two lines, but always gone wrong.
This is how look an example from the source:build_trigger = { owner = { adm_tech = 84 } religion_group = christian OR = { has_owner_religion = yes owner = { religion = secularism } } }
i want to change for this:
build_trigger = { }
I tried many things, but always mess up the entire text because not every condition has the same number of lines.
build_trigger = { province_is_or_accepts_religion = { religion = hellenism } }
Thank you in advance.
-
@Zoltán-Toldi said in Replace between two line:
always gone wrong.
Don’t feel bad. Regular expressions cannot parse nested pairs of delimiters, like the {…} in your files. You’re not succeeding because it’s not possible… at least not in a straightforward way.
You must be using some software that recognizes these files. If there is any way you can use that software to edit your files, instead of attempting to accomplish it with a text editor, you will be much more likely to succeed.
In your example, each opening
build_trigger = {
matches a}
at the same level of indentation, with everything enclosed indented further. If that is always true, without fail then you can use that to create your expression; this:(?s)^(\h*)build_trigger = {\R(\1\h.*?\R)*?\1}\R
should match your groups, which you can then replace with:
\1build_trigger = {\r\n\1}\r\n
to get what I think you want.
-
@Coises So many thanks for you.
-
@Coises said in Replace between two line:
Regular expressions cannot parse nested pairs of delimiters, like the {…} in your files. You’re not succeeding because it’s not possible… at least not in a straightforward way
There’s a technique for nested delimiter pairs, HERE. So, I disagree with the “not possible assessment”. But I definitely agree with the “not straightforward” assessment. :-)
Thus, for @Zoltán-Toldi 's problem in this thread, I suggest using the linked technique as a basis, to obtain:
Find:
(?-i)(\t+)build_trigger = (\{(?:[^{}]++|(?2))*\})
Replace:${1}build_trigger = {\r\n${1}}
Search mode: Regular expression -
This is TOML, I believe. I very strongly advise using a proper TOML parser for this, rather than any kind of fancy regex approach. Python’s tomllib should work fine. But of course I can’t say much beyond that, because this is not a general-purpose programming forum.
-
Hello, @zoltán-toldi, @coises, @alan-kilborn, @mark-olson and All,
This recursive example may be extended to any kind of leading section name !
For example, given this INPUT file :
build_trigger = { owner = { adm_tech = 84 } religion_group = christian OR = { has_owner_religion = yes owner = { religion = secularism } } } build_trigger = { province_is_or_accepts_religion = { religion = hellenism } } toto = { owner = { adm_tech = 84 } religion_group = christian OR = { has_owner_religion = yes owner = { religion = secularism } } } This is the Last test = { owner = { adm_tech = 84 } religion_group = guy AND = { has_owner_religion = yes OR = { owner = { religion = secularism } } Test_man = {guy038} } Value = { Test = 10 { Case = 8 } } }
The following recursive regex search/replacement :
SEARCH
(?-i)^(\t+)(.+) = (\{(?:[^{}]++|(?3))*\})
REPLACE
$1$2 = {\r\n$1}
Would produce this OUTPUT text :
build_trigger = { } build_trigger = { } toto = { } This is the Last test = { }
Best Regards,
guy038
-
Hi, @zoltán-toldi, @coises, @alan-kilborn, @mark-olson and All,
My previous regex may even be shortened as :
SEARCH
(?-i)^(\t+)(.+?)(\{(?:[^{}]++|(?3))*\})
REPLACE
$1$2{\r\n$1}
To better understand this second search regex, we can use the
free-spacing
modifier(?x)
. Then, the search regex becomes :(?x-i) ^ ( \t+ ) ( .+? ) ( \{ (?: [^{}]++ | (?3) )* \} ) 1-----1 2-----2 3-----------------------------3
So, after finding some leading tabs
\t+
and the shorter text.+?
, till an opening brace\{
, the regex tries to match, either :-
An atomic group of characters, different from an opening and closing braces, followed with a closing brace
-
An other group of characters ( the group
3
), starting with an opening brace\{
, which, in turn, can be followed with :-
An atomic group of characters, different from an opening and closing braces, followed with a closing brace
-
An other group of characters ( the group
3
), starting with an opening brace\{
, which, in turn can be followed with, either :
-
and so on …
Note that the third group
3
is called, from within the group itself, with the recursive back-reference(?3)
.When a group
x
is called from inside its own groupx
, thanks to the(?x)
syntax, this always defines a recursive regex !Note also that the use of the recursive
(?0)
syntax would refer to the whole regex$0
You can control the depth of the recursion by using the
{0,x}
syntax, instead of the*
, after the ending parenthese !Just try, against my INPUT example, the following values :
{0,1}
{0,2}
{0,3}
{0,4}
You can verify that, with my example, the
{0,4}
is enough to cover all the cases. Of course, the*
quantifier covers an infinite depth of recursion !BR,
guy038
-