有没有办法在字符值之前停止RegEx并在该字符后启动另一个?

时间:2013-04-23 20:51:12

标签: java regex

我正在尝试删除a-z*/+-等字符前的数字,然后删除以下任何数字那个角色,但在不同的角色之前。这就是我所拥有的。

    s= s.replaceAll("(\\d+)", "");
    s= s.replace("*", r.toString());

其中s是我需要阅读的字符串,r是操作的结果。

*是任意的。它可以是任何炭。前面提到的

这个问题是它删除了字符串中的每个数字。

如果我使用输入迭代一次:

    26 + 4 - 2

程序返回:

    30 - 

删除所有三个数字,然后将“+”替换为30。

我想将其更改为类似于此(一次迭代):

    26 + 4 - 2

第一个RegEx将删除第一组数字

    + 4 - 2

第二个会在运算符之后但在下一个运算符之前删除数字

    + - 2

下一个语句将使用表达式

的结果替换运算符
    30 - 2

对于其他函数(如正弦,余弦等)的问题我也一样。

注意:正弦是'a'

“Sin pi”与“a pi”相同

一次迭代后,它应该看起来像

    a pi + 2

    a + 2

    0 + 2

以下是代码示例。

这是Multiply“case”

    case '*':
                    {
                        int m = n + 1;
                        while (m < result.length){
                            if (result[m] != '*' && result[m] != '/' && result[m] != '+' && result[m] != '-'){ //checks the item to see if it is numeric
                                char ch2 = result[m]; //makes the number a character
                                number3 += new String(new char[]{ch2}); //combines the character into a string. For example: '2' + '3' = "23".
                                ++m;}
                            else {
                                    break;
                                }}
                        resultNumber = (Double.parseDouble(number2) * Double.parseDouble(number3)); //"number2" holds the value of the numbers before the operator. Example: This number ----> "3" '*' "23"
                        equation = equation.replaceAll("(\\d+)", "");  //  <---- Line I pulled out earlier that I want to change.
                        equation = equation.replace("*", resultNumber.toString()); // <----- Line I pulled out earlier
                        result = equation.toCharArray();
                        number3 = ""; //erases any number held
                        number2 = ""; //erases any number held
                        ++n;
                        break;
                    }

1 个答案:

答案 0 :(得分:0)

我首先会提出两种替代方法,然后回答你的问题。

也许没有正则表达式

我对你的申请有很多疑问。正确的tokenizer (lexer)以及非常简单的parser可能会比您的代码做得更好,并提供更清晰的错误消息。

匹配所有操作数

即使你要使用正则表达式,在一次传递中匹配两个操作数可能更有意义。即匹配(\d+)\s*\*\s*(\d+)以匹配恰好两个数字的乘法。您可以先搜索匹配项,然后从捕获组中提取操作数,然后计算结果值,最后将子字符串粘合在一起,包括结果:

// Multiplication of unparenthesized integers
Pattern p = Pattern.compile("(\\d+)\\s*\\*\\s*(\\d+)");
Matcher m = p.matcher(s);
while (m.find()) {
  int a = Integer.parseInt(m.group(1));
  int b = Integer.parseInt(m.group(2));
  s = s.substring(0, m.start(1)) + (a*b) + s.substring(m.end(2));
  m.reset(s);
}

回答标题

中的问题

关于问题的确切表述:

  

有没有办法在字符值之前停止RegEx并在该字符之后启动另一个?

如果您希望在输入中的给定字符后正则表达式不匹配,则可以通过负面的后置断言来实现。同样,要仅在给定角色之后匹配,您可以使用正面的后置断言。

所以从(?<!\*.*)开始的正则表达式只匹配第一次出现的'*',而从(?<=\*.*)开始的正则表达式只会在第一次出现该字符后才匹配。两者都必须使用DOTALL进行编译,或者使用更复杂的形式进行编译,例如(?<!\*(?:\n|.*)*)

但是确保这些匹配对应于你想到的数学可能会非常棘手。