用正则验证是否是一个有效的运算表达式
怎么写。类似:2-(-(-0.1))/(2*(-3*(2-(-3-(-5)*2+3))))
写了N次都毛了。
还有取得(-3-(-5)*2+3),但是不会取得(-0.1)这种的
这表达式怎么写。 

解决方案 »

  1.   

    try {} catch (exception e) {} 不行吗,一定要先验证?
      

  2.   

    太复杂了,可以用javacc来帮助解析。
      

  3.   


             /**
     * 获得类似:(+(+0.4)),(+(-0.4)),(+(0.4)),(-(+0.4)),(-(-0.4)),(-(0.4)),((+0.4)),((-0.4)),((0.4))等
     */
    public static final String rules_format = "\\(([\\+\\-]?)(\\([\\-\\+]?(([0-9]+\\.?[0-9]+)|([0-9]+))\\))\\)";
    /**
     * 表达式中的数字。不含有符号,例如:0.4,4,40等
     */
    public static final String rules_positive_number = "(([0-9]+\\.?[0-9]+)|([0-9]+))";/**
     * 括号内的运算表达式。
     */
    public static final String rules_bracket = "\\((((\\([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+))\\)|([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+)))|([0-9]+\\.?[0-9]+)|([0-9]+))([\\+\\-\\*\\/\\÷\\×]))+)(\\([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+))\\)|([0-9]+\\.?[0-9]+)|([0-9]+))\\)";        public static final char bracket_left = '(';

    public static final char bracket_right = ')';
    /**
     * 查找例似(+(-10.220))的表达式段并且格式化
     * 例如:(+(-10.220)) to (-10.220),(-(-10.220)) to 10.220,(-(+10.220)) to (-10.220)
     * @param numModel
     * @return
     */
    private static String formatNumModel(String numModel){
    StringBuffer sb = new StringBuffer(numModel);
    Pattern p = Pattern.compile(rules_format); //定义规则
    Matcher m = p.matcher(sb); //模板
    if(m.find()){
    return formatNumModel(m.replaceFirst(changeFormatNumModel(m.group())));
    }else{
    return sb.toString();
    }
    }

    /**
     * 格式化表达式段
     * for example:(+(-10.220)) to (-10.220),(-(-10.220)) to 10.220,(-(10.220)) to (-10.220)
     * @param numModel
     * @return
     */
    private static String changeFormatNumModel(String numModel){
    StringBuffer sb = new StringBuffer(numModel);
    char first = sb.charAt(sb.indexOf(String.valueOf(bracket_left))+1);
    char second = sb.charAt(sb.lastIndexOf(String.valueOf(bracket_left))+1);
    Pattern p = Pattern.compile(rules_positive_number); //定义规则
    Matcher m = p.matcher(sb); //模板
    m.find();
    String number = sb.substring(m.start(),m.end());
    if(first==second){
    return sb.substring(m.start(),m.end());
    }else{
    return new StringBuffer().append(bracket_left).append(subtract).append(number).append(bracket_right).toString();
    }
    }//首页去除掉(+(+0.4))类似的多余括号的表达式
    //再用rules_bracket表达式就能取得括号中的表达式。
    搞了半天也只能这个样子的了。
      

  4.   


    格式不好看,整理了下
    /**
         * 括号内的运算表达式。
         */
        public static final String rules_bracket = 
        "\\(" +
    "((" +
    "(" +
    "(\\([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+))\\))|" +
    "([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+)))|" +
    "([0-9]+\\.?[0-9]+)|" +
    "([0-9]+)" +
    ")" +
    "([\\+\\-\\*\\/\\÷\\×])" +
    ")+)" +
    "(" +
    "(\\([\\+\\-]?(([0-9]+\\.?[0-9]+)|([0-9]+))\\))|" +
    "([0-9]+\\.?[0-9]+)|" +
    "([0-9]+)" +
    ")" +
    "\\)";
      

  5.   

    这个用正则难度太高,因为不确定因素太多
    LZ还是用stack压栈出栈的方式,扫面字符串来判断吧
      

  6.   

    用ScriptEngine吧
      public static void main(String[] args) {
        System.out.println(test("2-(-(-0.1))/(2*(-3*(2-(-3-(-5)*2+3))))"));
        System.out.println(test("(-3-(-5)*2+3)"));
        System.out.println(test("(-0.1)"));
        System.out.println(test("xxxx"));
      }  public static boolean test(String expr) {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        try {
          Object result = engine.eval(expr);
          return (result instanceof Number);
        } catch (ScriptException e) {
          return false;
        }
      }