Mass replace and multiply at the same time
-
Dear all,
I’ve been using Notepad++ lately to edit scripts for my GTA server. In this case, it’s a car handling file.
I would like to edit the brakeforce. The file contains lots of information and I don’t want to edit each and every line. (Check exmaple)
How can I replace every “Brakeforce” line and increase the number by 20% (*1.2) at the same time?
This is what the text looks like:
<CHandlingDataMgr>
<HandlingData>
<Item type=“CHandlingData”>
<handlingName>AIRTUG</handlingName>
<fMass value=“1400.000000” />
<fInitialDragCoeff value=“30.000000” />
<fPercentSubmerged value=“85.000000” />
<vecCentreOfMassOffset x=“0.000000” y=“0.000000” z=“0.000000” />
<vecInertiaMultiplier x=“1.000000” y=“1.000000” z=“1.000000” />
<fDriveBiasFront value=“1.000000” />
<nInitialDriveGears value=“1” />
<fInitialDriveForce value=“0.060000” />
<fDriveInertia value=“1.000000” />
<fClutchChangeRateScaleUpShift value=“1.300000” />
<fClutchChangeRateScaleDownShift value=“1.300000” />
<fInitialDriveMaxFlatVel value=“40.000000” />
<fBrakeForce value=“0.300000” />
<fBrakeBiasFront value=“0.450000” />
<fHandBrakeForce value=“0.350000” />
<fSteeringLock value=“30.000000” />
<fTractionCurveMax value=“1.150000” />
<fTractionCurveMin value=“0.950000” />
<fTractionCurveLateral value=“11.000000” />
<fTractionSpringDeltaMax value=“0.100000” />
<fLowSpeedTractionLossMult value=“0.000000” />
<fCamberStiffnesss value=“0.000000” />
<fTractionBiasFront value=“0.450000” />
<fTractionLossMult value=“1.000000” />
<fSuspensionForce value=“4.000000” />
<fSuspensionCompDamp value=“1.500000” />
<fSuspensionReboundDamp value=“1.500000” />
<fSuspensionUpperLimit value=“0.100000” />
<fSuspensionLowerLimit value=“-0.100000” />
<fSuspensionRaise value=“0.000000” />
<fSuspensionBiasFront value=“0.500000” />
<fAntiRollBarForce value=“0.000000” />
<fAntiRollBarBiasFront value=“0.000000” />
<fRollCentreHeightFront value=“0.200000” />
<fRollCentreHeightRear value=“0.200000” />
<fCollisionDamageMult value=“1.000000” />
<fWeaponDamageMult value=“1.000000” />
<fDeformationDamageMult value=“2.000000” />
<fEngineDamageMult value=“1.500000” />
<fPetrolTankVolume value=“0.000000” />
<fOilVolume value=“0.000000” />
<fSeatOffsetDistX value=“0.000000” />
<fSeatOffsetDistY value=“0.000000” />
<fSeatOffsetDistZ value=“0.000000” />
<nMonetaryValue value=“15000” />
<strModelFlags>440000</strModelFlags>
<strHandlingFlags>1000</strHandlingFlags>
<strDamageFlags>20</strDamageFlags>
<AIHandling>TRUCK</AIHandling>
<SubHandlingData>
<Item type=“NULL” />
<Item type=“NULL” />
<Item type=“NULL” />
</SubHandlingData>
</Item>Best regards and thanks for your help!
Nitrobit
-
@Patrick-Szabo said in Mass replace and multiply at the same time:
How can I replace every “Brakeforce” line and increase the number by 20% (*1.2) at the same time?
Not with a regular expression as it does not have that sort of mathematical capability.
You could use a bookmark function to find each line and edit it. That would work for several dozen but a bit slow when doing lots.
By adding line numbers and then bookmarking you could extract just those lines and import into another program to perform that calculation (say Excel), then import back to Notepad++ and using the line numbers slot them back into their original position.
Using a supported language within Notepad++ such as pythonscript you could also achieve the answer, however that would entail either learning the language to program or hoping someone on this forum would do it for you. We try to be helpful here but it’s doubtful that will occur (quickly).
Good luckTerry
-
You could install the XML Tools plugin and use its XSL transformation feature.
- Go to
(menu) -> Plugins -> Plugins Admin
and install the XML Tools plugin. - After Notepad++ has been restarted copy the following code to a new document:
<?xml version="1.0" encoding="UTF-8"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8" indent="yes" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="fBrakeForce"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="value"> <xsl:value-of select="format-number(@value * 1.2, '0.000000')"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:transform>
- Save the document for example as
fBrakeForceTransform.xsl
. - Open the document you want to change and ensure that it is the active document.
- Go to
(menu) -> Plugins -> XML Tools -> XSL Transformation
. - In the dialog popping up click the
...
button and select the XSL file you saved in step 3. - Click the
Transform
button. - A new document will be created in Notepad++ with the transformed content. Save it to your hard disk.
Please note: Maybe you have to change the character encoding in line 7 of the XSL file to the encoding of your original document.
- Go to
-
Alternative python script for use with the Python Script plugin:
import xml.etree.ElementTree as ET root = ET.XML(editor.getText()) for brakeForce in root.findall(".//fBrakeForce"): if brakeForce is not None and brakeForce.attrib["value"] is not None: value = float(brakeForce.attrib["value"].strip()) * 1.2 brakeForce.attrib["value"] = "{:.6f}".format(value) editor.setText(ET.tostring(root))
-
@Patrick-Szabo said in Mass replace and multiply at the same time:
increase the number by 20% (*1.2) at the same time
My post in a similar thread (https://community.notepad-plus-plus.org/post/58111) answers nearly the same question with PythonScript – there is an example in the PS docs which shows how to apply a math function to any section of matched numbers. Customized for your formula:
def regexmath(m): return m.group(1) + "{:.6f}".format(float(m.group(2))*1.2) + m.group(3) editor.rereplace('(fBrakeForce value=")(\d*\.?\d*)(")', regexmath);
The rereplace splits the fBrakeForce line into three groups: the prefix, the value number, and the suffix; the regexmath callback leaves the first and third group unchanged, and changes the number to 1.2x the previous value.
However, regex are not the best choice for parsing XML, so both @Nick-Brown’s PythonScript+XML solution or @dinkumoil’s XML Tools solution are probably really better ideas, because they will handle the idiosyncracies of XML whereas my brute-force regex will be fragile if things change (for example, if some of your fBrakeForce lines have a second attribute before the value attribute).
-
Thank you guys so much! I didn’t expect someone to look into my problem and your solutions are well explained.
I’m very happy about your help!I’m going to try out the solutions now and come back with the result.
-
@dinkumoil I have tried your solution first and it worked. Thanks a lot for your support and effort!
This also goes for the other guys, I appreciate your time and effort a lot.
-
I was attempting to try out @Nick-Brown 's idea when I noticed the data as presented by @Patrick-Szabo has some problems with doing so.
Here’s the “same” data where it should work:
<CHandlingDataMgr> <HandlingData> <Item type="CHandlingData"> <handlingName>AIRTUG</handlingName> <fMass value="1400.000000" /> <fInitialDragCoeff value="30.000000" /> <fPercentSubmerged value="85.000000" /> <vecCentreOfMassOffset x="0.000000" y="0.000000" z="0.000000" /> <vecInertiaMultiplier x="1.000000" y="1.000000" z="1.000000" /> <fDriveBiasFront value="1.000000" /> <nInitialDriveGears value="1" /> <fInitialDriveForce value="0.060000" /> <fDriveInertia value="1.000000" /> <fClutchChangeRateScaleUpShift value="1.300000" /> <fClutchChangeRateScaleDownShift value="1.300000" /> <fInitialDriveMaxFlatVel value="40.000000" /> <fBrakeForce value="0.300000" /> <fBrakeBiasFront value="0.450000" /> <fHandBrakeForce value="0.350000" /> <fSteeringLock value="30.000000" /> <fTractionCurveMax value="1.150000" /> <fTractionCurveMin value="0.950000" /> <fTractionCurveLateral value="11.000000" /> <fTractionSpringDeltaMax value="0.100000" /> <fLowSpeedTractionLossMult value="0.000000" /> <fCamberStiffnesss value="0.000000" /> <fTractionBiasFront value="0.450000" /> <fTractionLossMult value="1.000000" /> <fSuspensionForce value="4.000000" /> <fSuspensionCompDamp value="1.500000" /> <fSuspensionReboundDamp value="1.500000" /> <fSuspensionUpperLimit value="0.100000" /> <fSuspensionLowerLimit value="-0.100000" /> <fSuspensionRaise value="0.000000" /> <fSuspensionBiasFront value="0.500000" /> <fAntiRollBarForce value="0.000000" /> <fAntiRollBarBiasFront value="0.000000" /> <fRollCentreHeightFront value="0.200000" /> <fRollCentreHeightRear value="0.200000" /> <fCollisionDamageMult value="1.000000" /> <fWeaponDamageMult value="1.000000" /> <fDeformationDamageMult value="2.000000" /> <fEngineDamageMult value="1.500000" /> <fPetrolTankVolume value="0.000000" /> <fOilVolume value="0.000000" /> <fSeatOffsetDistX value="0.000000" /> <fSeatOffsetDistY value="0.000000" /> <fSeatOffsetDistZ value="0.000000" /> <nMonetaryValue value="15000" /> <strModelFlags>440000</strModelFlags> <strHandlingFlags>1000</strHandlingFlags> <strDamageFlags>20</strDamageFlags> <AIHandling>TRUCK</AIHandling> <SubHandlingData> <Item type="NULL" /> <Item type="NULL" /> <Item type="NULL" /> </SubHandlingData> </Item> </HandlingData> </CHandlingDataMgr>
The problems were “curly” instead of “straight” double quotes, and the final two closing tags not being present.
Once this is resolved, yes, @Nick-Brown 's solution will work as well to change:
<fBrakeForce value="0.300000" />
into:
<fBrakeForce value="0.360000" />
-
Yes I did notice the same issue, I assumed it was the data posted in the forum and that the actual data was better formed.
Otherwise if it is meant to be XML it wasn’t valid with the curly quotes in it.
-
Yea, often posters just paste data into a posting without knowing what mangling a web site is going to do to it.
We recommend data be posted as a “code block” with the
</>
button in the composing toolbar, but asking for this seems to mystify a lot of people. -