我很确定这是被问到的&回答,但我找不到答案,所以我会问:
我想使用javas regex来查找和替换。没有涉及标记(没有,源代码字符串中的“$ {ImMarkup!}”,我希望替换的值是上下文化的(因为,我不能用B写一个简单的替换A)。
示例使一切变得更容易,这里是一些示例代码。这是源字符串:
! 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
我的正则表达式是
+(?<variableName>\w+) *= *-?(?<variableValue>\d+\.?\d*)
(注意第一个加号前的空格)
我希望用“x1 = 100”代替“x1 = 38000”,用“x2 = 200”代替“x2 = 2345”
输出
...
RMORE, ,
ET,MPTEMP,,,,EX, x1=100
x2 = 200
MPTEMP,,,,,,,,
...
我在这里创建了一个包含一些半可运行代码的要点(它使用了我们的公共代码库中的一些东西,但它可以跟随:https://gist.github.com/Groostav/acf5b584078813e7cbe6)
我得到的代码大致是
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);
正则表达式本身有效:它捕获我需要的值,我可以通过matcher.group(“variableName”)和matcher.group(“variableValue”)访问它们,我遇到的问题是写使用java regex API返回'variableValue'的新值。
在上面的例子中,matcher.group(“variableValue”)不会保持任何状态,所以我似乎无法指定我不想替换整行的appendReplacement()方法,而是简单地< / em>第二个捕获组。
值得研究,x1和x2不是硬性运行时名称,所以我不能简单地将它干酪化并为x1和x2分别编写查找和替换字符串。我需要runtime \ w +来查找变量名。
所以我可以针对第一个结果运行另一个正则表达式,这次只捕获值,但这并不漂亮,并且它需要我用StringBuilder / Buffer来捏造索引值,而不是那个好的索引 - 免费调用matcher.appendTail。
PS:你在上面看到的语言被称为“ANSYS参数化设计语言(APDL)”,我无法找到该语法的语法。如果你们中的任何一个人知道一个人在哪里,我会非常感激。
感谢阅读。
答案 0 :(得分:1)
答案 1 :(得分:0)
我的Hacky解决方案似乎有效,是手动遍历我们的解析树,沿着rhs,并替换新值。这很烦人,因为它需要我重构我的正则表达式并完成手工工作,但它确实可以完成这项工作,我相信它的可靠性:
// semi-formally, APDL seems to define:
// AssignmentExpression -> QualifiedIdentifier = Expression
// QualifiedIdentifier -> SPACE+ Identifier SPACE*
// Expression -> SPACE* Value //Value is captured as "value"
// Identifier -> [A-Za-z0-9]* //Identifier is captured as "identifier"
// Value -> [0-9]* (DOT [0-9]*)?
private static final String rValue = "\\d+(\\.\\d*)?";
private static final String rIdentifier = "(?<identifier>\\w+)";
private static final String rQualifiedIdentifier = " +" + rIdentifier + " *";
private static final String rExpression = " *-?(?<value>" + rValue + ")";
private static final String rAssignmentExpression = rQualifiedIdentifier + "=" + rExpression;
@Test
public void when_scanning_using_our_regex(){
Pattern assignmentPattern = Pattern.compile(rAssignmentExpression);
Pattern rhsPattern = Pattern.compile("=" + rExpression);
Pattern valuePattern = Pattern.compile(rValue);
Matcher assignmentMatcher = assignmentPattern.matcher(sourceText);
StringBuffer output = new StringBuffer();
int newValue = 20;
while(assignmentMatcher.find()){
String assignment = assignmentMatcher.group();
Matcher rhsMatcher = rhsPattern.matcher(assignment);
assert rhsMatcher.find() : "couldn't find an RHS in an the assignment: '" + assignment + "'?";
String oldRhs = rhsMatcher.group();
Matcher valueMatcher = valuePattern.matcher(oldRhs);
assert valueMatcher.find() : "couldn't find a value in an RHS: '" + oldRhs + "'?";
String oldValue = valueMatcher.group();
String newRhs = oldRhs.replace(oldValue, "" + newValue);
String newAssignment = assignment.replace(oldRhs, newRhs);
assignmentMatcher.appendReplacement(output, "" + newAssignment);
}
assignmentMatcher.appendTail(output);
System.out.println(output.toString());
}