YAML extension, Search 2 Value and Replace
-
Hi,
Here is an example of what I want to change:Id: 840002 AegisName: Adulter_F_Launcher Name: Adulter Fides Launcher Type: Weapon SubType: Grenade Weight: 3000 Attack: 350 Range: 9 Slots: 2 Jobs: Rebellion: true Locations: Both_Hand: true WeaponLevel: 4 EquipLevelMin: 180 Script: | .@r = getrefine(); bonus2 bSkillAtk,"RL_D_TAIL",10; bonus bBaseAtk,18*(.@r/3); if (.@r>=7) { bonus2 bSkillAtk,"RL_D_TAIL",20; if (.@r>=9) { bonus2 bSkillCooldown,"RL_D_TAIL",-2000; if (.@r>=11) { bonus2 bSkillAtk,"RL_D_TAIL",25; if (.@r>=12) { bonus bLongAtkRate,15; }
I want to search for these two value in every Id table:
Type: Weapon
Slots: 2And change the slots to:
Slots: 4
These slots can have a value between 0-4Thank you in advance…
-
-
The file format is mildly different than the one from your last question, but the concept of the answer will still be the same. However, since re-reading that thread, I see that they never explained how it worked, or even linked you to our regex FAQ, so you’ll get a second freebie out of this one.
While typing this up, I saw that @astrosofista beat me to an answer. However, I made a more-restrictive answer, assuming that the Weapon and Slots had to be within the same
Id:
block in your YAML. However, his looks a lot more like what @guy038 presented in the last question. So I will present it here.- FIND =
(?sx) ^Id: ((?!^Id:).)* (Type:\h*Weapon) ((?!^Id:).)* Slots:\h*\K[0-4]
- REPLACE =
4
- MODE = Regular Expression
- hit REPLACE ALL
Mine will take shortened example data like the following:
Id: 840002 AegisName: Something Type: Weapon OtherParameters: here Slots: 2 Id: 840003 AegisName: Different Type: Flower OtherParameters: here Slots: 2 Id: 840004 AegisName: Something Type: Weapon OtherParameters: here Slots: 0
and convert it to
Id: 840002 AegisName: Something Type: Weapon OtherParameters: here Slots: 4 Id: 840003 AegisName: Different Type: Flower OtherParameters: here Slots: 2 Id: 840004 AegisName: Something Type: Weapon OtherParameters: here Slots: 4
… notice that the Flower doesn’t change its slots, but the two weapons do.
A brief explanation of each piece:
(?sx)
= this turns on. matches newline
and makes it so that spaces in the regex are for readability (and to match a literal space character, you have to use one of the escape characters, like\x20
for just the space, or\h
for space-or-tab)^Id:
= matchesId:
as long as it is at the start of the line((?!^Id:).)*
= fancy: this matches any character, as long as the character isn’t the start of^Id:
(ie, as long as it doesn’t go into the next Id block)(Type:\h*Weapon)
= this matchesType:
followed by 0 or more spaces or tabs, followed byWeapon
((?!^Id:).)*
= same as beforeSlots:\h*
= matchesSlots:
followed by 0 or more spaces or tabs\K
= this resets the match, so we don’t need to have stored all the previous stuff, even though all that went before must match.
Unfortunately, this has the side effect of requiring REPLACE ALL instead of doing single REPLACE multiple times.[0-4]
= this is the 0-4 slots that you said might be there
My replacement then just replaces the 0-4 with the literal 4
Also, here is some useful information that I post to people new to regular expressions. Please read and understand and follow the information under here (and that it links to).
----
Please note: This Community Forum is not a data transformation service; you should not expect to be able to always say “I have data like X and want it to look like Y” and have us do all the work for you. If you are new to the Forum, and new to regular expressions, we will happily give help on the first one or two data-transformation questions, especially if they are well-asked and you show a willingness to learn; and we will point you to the documentation where you can learn how to do the data transformations for yourself in the future. But if you repeatedly ask us to do your work for you, you will find that the patience of usually-helpful Community members wears thin. The best way to learn regular expressions is by experimenting with them yourself, and getting a feel for how they work; having us spoon-feed you the answers without you putting in the effort doesn’t help you in the long term and is uninteresting and annoying for us.
----
Do you want regex search/replace help? Then please be patient and polite, show some effort, and be willing to learn; answer questions and requests for clarification that are made of you. All example text should be marked as literal text using the
</>
toolbar button or manual Markdown syntax. To makeregex in red
(and so they keep their special characters like *), use backticks, like`^.*?blah.*?\z`
. Screenshots can be pasted from the clipboard to your post usingCtrl+V
to show graphical items, but any text should be included as literal text in your post so we can easily copy/paste your data. Show the data you have and the text you want to get from that data; include examples of things that should match and be transformed, and things that don’t match and should be left alone; show edge cases and make sure you examples are as varied as your real data. Show the regex you already tried, and why you thought it should work; tell us what’s wrong with what you do get. Read the official NPP Searching / Regex docs and the forum’s Regular Expression FAQ. If you follow these guidelines, you’re much more likely to get helpful replies that solve your problem in the shortest number of tries. - FIND =
-
@astrosofista
thank you sir! -
@PeterJones
I have copied your first search example that you have given me and tried it in this new search criteria. Change it a bit with no success. I got into thinking that tabs and spaces have an effect on the search.
Thank you for the link. I read it, but it doesn’t clearly sink into my brain.
I will search on YouTube and hope there will be examples on every code it presents.
Thank you very much! -
@Mark-Lozada said in YAML extension, Search 2 Value and Replace:
Change it a bit with no success
If you don’t tell us what you tried, we cannot help you figure out what you’re doing wrong.
I got into thinking that tabs and spaces have an effect on the search.
Yes, very much so.
The answers you get are only going to be as good as the examples and description you give.
And if @astrosofista’s works for you, just use that one. I made my regex more complex in order to make it more restrictive.
But back to mine: If
Id:
isn’t actually at the beginning of the line in your real data like it was in the example you gave us, but instead has spaces or tabs before it, take the regex I gave and change every instance of^Id:
into^\h*Id:
– so FIND =(?sx) ^\h*Id: ((?!^\h*Id:).)* (Type:\h*Weapon) ((?!^\h*Id:).)* Slots:\h*\K[0-4]
Thank you for the link. I read it, but it doesn’t clearly sink into my brain.
Considering my post had multiple links…
Assuming you meant you read the entirety of the npp-user-manual.org/docs/searching#regular-expressions section – there is a lot to digest there. You cannot expect to become an expert in one day. But you can look up the individual pieces in that document, and try to figure out what they are doing in this context. My description of each chunk should help with that.
-
I forgot to add the “-” on the “Id:”
So I edited your search to:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Slots:\h*[0-4]
This regex((?!\-\s Id:).)*
really helps a lot not jumping to the next “Id:”
Can you tell me the difference between this regex(?s-i)
to(?sx)
?And also I noticed in my data that I have Id’s that doesn’t have a slot entry where it should have one, so I need to insert a
\w
with this value “Slot: 4”
Below is the example YAML:- Id: 1152 AegisName: Slayer_ Name: Slayer Type: Weapon SubType: 2hSword Buy: 15000 Weight: 1300 Attack: 90 Range: 1 Slots: 3 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true - Id: 1153 AegisName: Slayer__ Name: Slayer Type: Weapon SubType: 2hSword Buy: 15000 Weight: 1300 Attack: 90 Range: 1 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true - Id: 1154 AegisName: Bastard_Sword Name: Bastard Sword Type: Weapon SubType: 2hSword Buy: 22500 Weight: 1600 Attack: 115 Range: 1 Slots: 2 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true
Notice that Id:1153 is missing the Slot entry if I change the regex search to:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Range:\h*[0-4]
and replace it with:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Slots:\h*[0-4]\rSlots:\s4
would do duplicate Slots entry on the “Id:” that already has it -
@Mark-Lozada said in YAML extension, Search 2 Value and Replace:
I forgot to add the “-” on the “Id:”
So I edited your search to:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Slots:\h*[0-4]
This regex((?!\-\s Id:).)*
really helps a lot not jumping to the next “Id:”
Can you tell me the difference between this regex(?s-i)
to(?sx)
?And also I noticed in my data that I have Id’s that doesn’t have a slot entry where it should have one, so I need to insert a
\w
with this value “Slot: 4”
Below is the example YAML:- Id: 1152 AegisName: Slayer_ Name: Slayer Type: Weapon SubType: 2hSword Buy: 15000 Weight: 1300 Attack: 90 Range: 1 Slots: 3 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true - Id: 1153 AegisName: Slayer__ Name: Slayer Type: Weapon SubType: 2hSword Buy: 15000 Weight: 1300 Attack: 90 Range: 1 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true - Id: 1154 AegisName: Bastard_Sword Name: Bastard Sword Type: Weapon SubType: 2hSword Buy: 22500 Weight: 1600 Attack: 115 Range: 1 Slots: 2 Jobs: Crusader: true Knight: true Swordman: true Locations: Both_Hand: true WeaponLevel: 2 EquipLevelMin: 18 Refineable: true
Notice that Id:1153 is missing the Slot entry if I change the regex search to:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Range:\h*[0-4]
and replace it with:
(?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Slots:\h*[0-4]\rSlots:\s4
would do duplicate Slots entry on the “Id:” that already has itCorrection
Search:
((?sx) \-\s Id: ((?!\-\s Id:).)* (Type:\h*Weapon) ((?!\-\s Id:).)* Range:\h*[0-4])
Replace:
\1\r\tSlots: 4
-
I forgot to add the “-” on the “Id:” …
Good job on figuring out a way around that.
Can you tell me the difference between this regex
(?s-i)
to(?sx)
?I thought the documentation on search modifiers section on
(?enable-disable)
went into that: items before the-
are enabled, and items after the-
are disabled; that section explains what each of thei
,m
,s
, andx
modifiers do. So(?s-i)
enabless
(dot matches newline) and disablesi
(disables case-insensitive, so makes the match case sensitive). Whereas(?sx)
enables boths
andx
, so dot matches newline is still enabled, and ignore whitespace is enabled (so you can add extra spaces in the regex to make it more readable, but that means you have to escape literal whitespace)I have Id’s that doesn’t have a slot entry where it should have one
There are ways that it could be done. But it’s getting super-complicated. Sometimes, it’s better to simplify the problem if at all possible.
I am noticing in your data that Slots is always coming after Range (and your suggested regex with Range at the end seems to confirm that).
I might do the missing Slots check as something simpler like “if Range isn’t followed by Slots, add Slots”.
- FIND =
Range: \d+(\s*)(?!Slots: \d+)
- This looks for Range with an integer.
- Then it stores the whitespace (including tabs and newlines) in group#1 – so it captures the newline plus indent between the range and the next e
- Then it looks ahead for a tag that isn’t the number of slots
- REPLACE =
$0$1Slots: 4
- The
$0
is the entirety of the matched text from FIND - the
$1
is the text from group#1 – this means that we add another newline and indent - add in the literal number of slots
- The
This doesn’t confirm that it’s in a
Type: Weapon
section. But maybe if it has a range, it will always have slots. If not, you could hybridize this idea for the replacement with what you’ve been given before to only do the replacement if there’s no Slots after Range in a Weapon. - FIND =
-
@PeterJones
I have my final search string, thanks to you sir! In order for the search to distinguish if it’s missing the “Slots” entry, I have to searched from "Range: to “Job:”Search:
(Range: \d)+(\s*)(?!Slots: \d+)(\s*)Jobs:$
Replace:
\1 \r\n\tSlots: 4 \r\n\tJobs: