使用java查找和替换而不使用标记

使用java查找和替换而不使用标记,java,regex,Java,Regex,我相当肯定这是问和答,但我找不到(那个)答案,所以我会问: 我想使用javasregex来查找和替换。没有涉及任何标记(不,“${ImMarkup!}在源字符串中),并且我希望替换的值是上下文化的(例如,我无法编写简单的用B替换a) 示例使一切变得更简单,下面是一些示例代码。这是源字符串: ! locator's position P1(p1x,p1y),P2(p2x,p2y) R,1,0.001,0.001,0.001,0.001, , , RMORE, , , , RMORE RMOR

我相当肯定这是问和答,但我找不到(那个)答案,所以我会问:

我想使用javasregex来查找和替换。没有涉及任何标记(不,“${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*)
我在这里创建了一个包含一些半可运行代码的要点(它使用了我们的commons代码库中的一些东西,但它可以如下所示:)

我得到的代码大致是

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);
String regex=“+(?\\w+)*=*-(?\\d+\.?\\d*)”
Pattern=Pattern.compile(regex);
Matcher Matcher=pattern.Matcher(sourceText);
while(matcher.find()){
字符串variableName=matcher.group(“variableName”);
字符串existingValue=matcher.group(“variableValue”);
int新值;
开关(变量名称){
案例“x1”:新值=100;中断;
案例“x2”:新值=200;中断;
默认值:抛出新的IllegalStateException();
}
matcher.appendReplacement(输出“”+newValue);
}
matcher.appendTail(输出);
正则表达式本身可以工作:它捕获我需要的值,我可以通过matcher.group(“variableName”)和matcher.group(“variableValue”)访问它们,我遇到的问题是使用java正则表达式API将新值写回“variableValue”

在上面的示例中,matcher.group(“variableValue”)不保持任何状态,因此我似乎无法向appendReplacement()方法指定我不想替换整行,而只是替换第二个捕获组

值得一提的是,x1和x2不是快速的运行时名称,因此我不能简单地将其压缩并为x1和x2编写单独的查找和替换字符串。我需要运行时\w+来查找变量名

因此,我可以针对第一个结果运行另一个正则表达式,这次只捕获值,但这并不漂亮,这可能需要我使用StringBuilder/Buffer来伪造索引值,而不是调用matcher.appendTail

PS:你在上面看到的语言叫做“ANSYS参数化设计语言(APDL)”,我找不到它的语法。如果你们中有人知道它在哪里,我将非常感激


感谢阅读。

您可以使用此正则表达式:

(\w+\s*)=(\s*\d+)


检查替换部分。您可以使用与我使用捕获组索引相同的方法来替换所需内容。

我的黑客解决方案似乎有效,就是手动遍历解析树,向下遍历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());

}
//半正式地说,APDL似乎定义了:
//AssignmentExpression->QualifiedIdentifier=表达式
//限定标识符->空格+标识符空格*
//表达式->空格*值//值被捕获为“值”
//标识符->[A-Za-z0-9]*//标识符被捕获为“标识符”
//值->[0-9]*(点[0-9]*)?
私有静态最终字符串rValue=“\\d+(\\.\\d*)?”;
私有静态最终字符串rIdentifier=“(?\\w+”;
私有静态最终字符串rQualifiedIdentifier=“+”+rIdentifier+“*”;
私有静态最终字符串rExpression=“*-?(?“+rValue+””);
私有静态最终字符串rAssignmentExpression=rQualifiedIdentifier+“=”+rExpression;
@试验
使用我们的正则表达式()扫描时公共无效{
Pattern assignmentPattern=Pattern.compile(rAssignmentExpression);
Pattern rhsPattern=Pattern.compile(“=”+rExpression);
Pattern-valuePattern=Pattern.compile(右值);
Matcher assignmentMatcher=assignmentPattern.Matcher(sourceText);
StringBuffer输出=新的StringBuffer();
int newValue=20;
while(assignmentMatcher.find()){
字符串赋值=assignmentMatcher.group();
匹配器rhsMatcher=rhsPattern.Matcher(分配);
assert rhsMatcher.find():“在赋值中找不到RHS:”“+assignment+”?”;
字符串oldRhs=rhsMatcher.group();
Matcher valueMatcher=valuePattern.Matcher(oldRhs);
assert valueMatcher.find():“在RHS中找不到值:'”+oldRhs+“?”;
字符串oldValue=valueMatcher.group();
字符串newRhs=oldRhs.replace(oldValue,“+newValue);
字符串newAssignment=assignment.replace(oldRhs,newRhs);
assignmentMatcher.appendReplacement(输出“”+newAssignment);
}
assignmentMatcher.appendTail(输出);
System.out.println(output.toString());
}

ahh,谢谢,但我实际上对编写正则表达式本身没有问题,我实际上对如何使用替换机制有问题。无论如何,谢谢!替换整个匹配,但通过预先设置第一个捕获组和a=,重建它怎么样。@Groostav感谢+1。顺便说一句,答案的想法是向您展示使用捕获组替换内容的技术。您可以尝试Markus comment。检查我提供的链接,并在替换部分测试此功能。因此我们确实找到了一种方法,我正在使用下面的hack,但我非常感谢您指出此工具。它的解释很好,它的UI很简单,似乎与Java Regex interp兼容reter.和它的平面引导。好东西。当你有机会时,请你澄清文本和替换发生在哪里添加(放置文本在这里)放置(替换文本在这里),我可以用它来查找和替换错误的邮政编码与正确的吗
// 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());

}