Java正则表达式到javascript正则表达式的问题

Java regexp To javascript regex problems

本文关键字:正则表达式 问题 Java javascript      更新时间:2023-09-26

我有一个javascript regexp的问题。这是我的正则表达式:

((['+'-'/'*'^]?)([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*)?(([(]*([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?)[)]*))?(['+'-'/'*'^])([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*))+

这个regexp测试如果文本是一个数学公式(18*19)/2为例,我可以添加QXX像一个变量,例如:Q18/42+7*Q7

这个正则表达式在java中工作完美(我已经在http://fiddle.re/dnbh6上测试过了)。但是,当我试图转换它在javascript,它不工作…这是我尝试过的所有解决方案:

var reg =/((['+'-'/'*'^]?)([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*)?(([(]*([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?)[)]*))?(['+'-'/'*'^])([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*))+/g;
reg.test("Q18+aaaa)//return true, but in java this is resturn false
var reg= new RegExp("((['+'-'/'*'^]?)([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*)?(([(]*([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?)[)]*))?(['+'-'/'*'^])([(]*(([(]?((([+-]?'d+([.,]?('d+)?)?)|(Q[0-9]+)?)([e][+-]'d+)?)[)]?)|([(]?value[)]?))[)]*))+", "g");
reg.test("Q18+aaaa)//return true, but in java this is resturn false

所以,如果你有任何想法,我将尝试。

我不确定你在这里做的事情是否正确,但我想我知道你的问题是什么。

在Java中,如果您正在使用matches()方法,它将针对完整的字符串匹配正则表达式。

Javascript没有这样做,它也返回部分匹配。要实现相同的行为,您必须在正则表达式周围添加锚。^匹配字符串的开头,$匹配字符串的结尾。

所以它应该看起来像这样(缩短了巨大的regex!):

var reg= new RegExp("^((['+'-'/'*'^]?)...([(]?value[)]?))[)]*))+$", "g");
  Added anchors ==>  ^                                          ^

从这个正则表达式上的括号数量来看,我假设您不想捕获任何数据。验证输入的更好的正则表达式可能是这样的:

/
   [(](?R)[)] # match parenthesis
   |(?R)[-+/*^](?R) # allow to use one operator over to operands
   # a number, can be separated by "," or "." and can be followed by a exponent,
   # do _not_ accept decimal mark
   |[+-]?'d+([,.]'d+)?(e[+-]'d+)?
   |Q[0-9]+(e[+-]'d+)?
   |value
/x

因为递归你不能使用锚,而且,我使用了PCRE的(?R),你将需要一些库支持来做递归,正如在评论中所说的。

编辑:如果你想保存数据,你可以写一个解析函数,有以下大纲:

function parse(input) {
    var output = [],
        brackets = 0,
        op = null,
        qvariable = false,
        buff = [],
        stringbuff = '',
        sign = null;
    for (i = 0; i < input.length; i++) {
        var currentChar = input.charAt(i);
        if (sign && /[0-9]/.test(currentChar)) {
            return 'erro, expecting number';
        }
        if (op != null && /[-+/*(]/.test(currentChar)) {
            op = null;
        }
        switch (currentChar) {
            case '(':
                buff.push(output);
                output = [];
                break;
            case ')':
                if (op != null) { return 'operator before parenthesis close'; }
                output.push(stringbuff);
                parenthesis = output
                output = buff.pop();
                output.push(parenthesis);
                stringbuff = '';
                break;
            case '-':
            case '+':
            case '/':
            case '*':
                if (op == null) {
                    op = currentChar;
                } else {
                    if (currentChar == '-' && currentChar == '+') {
                        sign = currentChar;
                    } else {
                        return 'error, two operators in sequence';
                    }
                }
                output.push(stringbuff);
                output.push(op);
                stringbuff = '';
                break;
            case 'Q':
                if (!stringbuff.length) { return null; }
                qvariable = true;
                stringbuff += currentChar;
            // todo: handle comma, dot and exponents
            default:
                if (/[0-9]/.test(currentChar)) {
                    if (sign) { 
                        stringbuff += sign;
                        sign = null;
                    }
                    stringbuff += currentChar;
                } else {
                    return 'unexpected input';
                }
                break;
        }
    }
    if (stringbuff.length) {
        output.push(stringbuff);
    }
    return output;
}