I'm fairly certain this is asked & answered, but I cant find an (that) answer, so I'll ask:
I want to use javas regex to find and replace. There is no markup involved (no, "${ImMarkup!} in the source string) and the value I wish to replace is contextualized (as in, I cant write a simple replace A with B).
Examples make everything easier, here's some sample code. This is the source string:
! locator's position P1(p1x,p1y),P2(p2x,p2y)
R,1,0.001,0.001,0.001,0.001, , ,
RMORE, , , ,
RMORE
RMORE, ,
ET,MPTEMP,,,,EX, x1=38000
x2 = 2345
MPTEMP,,,,,,,,
MPTEMP,1,0
MPDATA,EX,1,,38000*6894.75
my regex is
+(?<variableName>\w+) *= *-?(?<variableValue>\d+\.?\d*)
(note the space before the first plus)
I'm looking to replace that "x1=38000" with something like "x1=100", and the "x2 = 2345" with "x2 = 200"
With the output
...
RMORE, ,
ET,MPTEMP,,,,EX, x1=100
x2 = 200
MPTEMP,,,,,,,,
...
I've created a gist containing some semi-runnable code here (it uses some stuff from our commons code base, but its followable: https://gist.github.com/Groostav/acf5b584078813e7cbe6)
The code I've got is roughly
String regex = "+(?<variableName>\\w+) *= *-?(?<variableValue>\\d+\\.?\\d*)"
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(sourceText);
while(matcher.find()){
String variableName = matcher.group("variableName");
String existingValue = matcher.group("variableValue");
int newValue;
switch(variableName){
case "x1": newValue = 100; break;
case "x2": newValue = 200; break;
default: throw new IllegalStateException();
}
matcher.appendReplacement(output, "" + newValue);
}
matcher.appendTail(output);
The regex itself works: it captures the values I need, and I can access them through matcher.group("variableName") and matcher.group("variableValue"), the issue I'm having is writing a new value back to 'variableValue', with the java regex API.
In the above example, matcher.group("variableValue") doesnt persist any state, so I cant seem to specify to the appendReplacement() method that I dont want to replace the whole line, but rather simply the second capture group.
Worth metnioning, x1 and x2 are not hard-fast runtime names, so I cant simply cheese it and write separate find and replace strings for x1 and x2. I need the runtime \w+ to find the variable name.
So I can run another regex against the result of the first, this time only capturing the value, but thats not pretty, and it would require me to probably fudge index values around with our StringBuilder/Buffer, rather than that nice index-free call to matcher.appendTail.
PS: the langauge you see above is called the "ANSYS parametric design language (APDL)", and I cant find a grammar for the thing. If any of you guys know where one is, I'd hugely appreciate it.
thanks for reading.