2014-09-21 122 views
2

我有我从中提取从特定四处旅行运营商的线性表达式不需要提取所有operators.ie我的表达是如何使用正则表达式

c*(a+b)+(a-b)/log(a+b)-(b-c/d)+(d-tan90) 
提取从线性表达式的特定部分操作员

括号内的操作符不需要分开。只有在两个元素之间的操作员才会被分开.i.e我的期望输出将是

*,+,/, - ,+ 任何人都可以帮忙吗?

+4

建议:不要使用正则表达式来“解析”表达式。要么找到现有的表达式解析器,要么自己写一个。 – 2014-09-21 03:21:46

+0

你能建议吗? – Subho 2014-09-21 03:27:05

+0

尽管这不像尝试[用正则表达式解析HTML]那样糟糕(http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454# 1732454),您仍然可以使用或编写像@StephenC所建议的解析器。迭代表达式并丢弃括号中的所有内容并存储操作符应该相当简单。 – azurefrog 2014-09-21 03:27:29

回答

1

如果你真的需要的是运营商,我认为表达式分析器是矫枉过正的。

只需循环访问字符并存储操作员就很简单。唯一的(小)复杂性是跟踪括号的数量。

这个片段会给你所需的输出,如果你结束了嵌套表达式也将工作:

String expression = "c*(a+b)+(a-b)/log(a+b)-(b-c/d)+(d-tan90)"; 
    List<Character> operators = new ArrayList<Character>(); 
    int parentheses = 0; 
    for (char c : expression.toCharArray()) { 
     // throw away everything inside () 
     if (c == '(') { 
      parentheses++; 
     } else if (c == ')') { 
      parentheses--; 
     } 
     if (parentheses > 0) { 
      continue; 
     } 

     // store operators outside () 
     if (c == '+' || c == '-' || c == '*' || c == '/') { 
      operators.add(c); 
     } 
    } 
    System.out.println(operators); // [*, +, /, -, +] 

请注意,我假设你正在开发一个有效的数学表达式在这里。如果你不确定你会得到很好的输入,你需要验证它。

如果您打算做更奇特的事情,您可能需要使用表达式解析器(例如JepFormula4J)。

+0

感谢它正在为我工​​作 – Subho 2014-09-21 03:48:48

1

假设没有嵌套圆括号,可以通过删除不需要的字符序列来实现。你并不需要的字符序列是:

  • 任意以()结束序列;
  • 其他任何不是操作员的字符。

您可以使用replaceAll丢弃所有这些序列。该语句将设置operators为字符串与所有这些去除,即"*+/-+"

operators = inputString.replaceAll("\\([^)]*\\)|[^-+*/]", ""); 

这使得任何一个(组成序列,随后的零个或多个非)字符,接着)""被替换;它也会导致任何不是-,+,*/的字符将被替换为""。第一种方法是先测试,所以第二种方法只会影响不在括号内的字符。请注意,[^-+*/]中的连字符先出现在任何其他字符之前,这样-不会被解释为指示一系列字符。

如果嵌套圆括号是可能的,那么不要使用正则表达式。 Java中的正则表达式无法处理嵌套的构造。 (我认为有些语言支持正则表达式来处理它们,但不支持Java,至少不是标准的Java运行时,可能会有第三方Java库支持它)。azurefrog的答案是最好的方法。

注意:现在测试。

+0

虽然嵌套圆括号不能用经典的正则表达式来处理,但Java'Pattern'正则表达式比(从理论角度)更强大。然而,一个可以处理递归语法的正则表达式可能太**粗糙;即对于大多数人来说读/写太复杂了。你应该避免这种做法*出于这个原因*。 – 2014-09-21 03:48:12