我有一个文本文件,其中包含一些数学表达式。 我需要使用正则表达式将文本解析为组件(单词、句子、标点符号、数字和算术符号),计算数学表达式并使用计算出的数字表达式以原始形式返回文本。 我没有使用正则表达式(没有计算)来完成此操作。现在我正在尝试使用正则表达式来做到这一点。 我不完全明白如何正确地做到这一点。输入的文字是这样的:
Pete like mathematic 5+3 and jesica too sin(3).
在我需要的输出中:
Pete like mathematic 8 and jesica too 0,14.
我需要知道如何执行此操作的人提供一些有关正则表达式和计算的建议。
我的代码:
final static Pattern PUNCTUATION = Pattern.compile("([\\s.,!?;:]){1,}");
final static Pattern LETTER = Pattern.compile("([а-яА-Яa-zA-Z&&[^sin]]){1,}");
List<Sentence> sentences = new ArrayList<Sentence>();
List<PartOfSentence> parts = new ArrayList<PartOfSentence>();
StringTokenizer st = new StringTokenizer(text, " \t\n\r:;.!?,/\\|\"\'",
true);
带有正则表达式的代码(不起作用):
while (st.hasMoreTokens()) {
String s = st.nextToken().trim();
int size = s.length();
for (int i=0; i<s.length();i++){
//with regex. not working variant
Matcher m = LETTER.matcher(s);
if (m.matches()){
parts.add(new Word(s.toCharArray()));
}
m = PUNCTUATION.matcher(s);
if (m.matches()){
parts.add(new Punctuation(s.charAt(0)));
}
Sentence buf = new Sentence(parts);
if (buf.getWords().size() != 0) {
sentences.add(buf);
parts = new ArrayList<PartOfSentence>();
} else
parts.add(new Punctuation(s.charAt(0)));
没有正则表达式(工作):
if (size < 1)
continue;
if (size == 1) {
switch (s.charAt(0)) {
case ' ':
continue;
case ',':
case ';':
case ':':
case '\'':
case '\"':
parts.add(new Punctuation(s.charAt(0)));
break;
case '.':
case '?':
case '!':
parts.add(new Punctuation(s.charAt(0)));
Sentence buf = new Sentence(parts);
if (buf.getWords().size() != 0) {
sentences.add(buf);
parts = new ArrayList<PartOfSentence>();
} else
parts.add(new Punctuation(s.charAt(0)));
break;
default:
parts.add(new Word(s.toCharArray()));
}
} else {
parts.add(new Word(s.toCharArray()));
}
}
最佳答案
这不是一个需要解决的小问题,因为即使是匹配的数字也会变得非常复杂。
首先,数字可以通过正则表达式“(\\d*(\\.\\d*)?\\d(e\\d+)?)”
来匹配,以考虑小数位和指数格式。
其次,您想要解决(至少)三种类型的表达式:二元、一元和函数。对于每一个,我们创建一个模式以在 solve
方法中匹配。
第三,有许多库可以实现reduce
方法,例如this或this .
下面的实现不处理嵌套表达式,例如 sin(5) + cos(3)
或表达式中的空格。
private static final String NUM = "(\\d*(\\.\\d*)?\\d(e\\d+)?)";
public String solve(String expr) {
expr = solve(expr, "(" + NUM + "(!|\\+\\+|--))"); //unary operators
expr = solve(expr, "(" + NUM + "([+-/*]" + NUM + ")+)"); // binary operators
expr = solve(expr, "((sin|cos|tan)\\(" + NUM + "\\))"); // functions
return expr;
}
private String solve(String expr, String pattern) {
Matcher m = Pattern.compile(pattern).matcher(expr);
// assume a reduce method :String -> String that solve expressions
while(m.find()){
expr = m.replaceAll(reduce(m.group()));
}
return expr;
}
//evaluate expression using exp4j, format to 2 decimal places,
//remove trailing 0s and dangling decimal point
private String reduce(String expr){
double res = new ExpressionBuilder(expr).build().evaluate();
return String.format("%.2f",res).replaceAll("0*$", "").replaceAll("\\.$", "");
}
关于Java正则表达式从txt文件输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41502232/