Java 如何更改正则表达式以正确匹配浮点文本?
我试图为java表达式创建一个解析器,但由于某些原因,我无法匹配浮点值。我使用的是从Java 如何更改正则表达式以正确匹配浮点文本?,java,regex,parsing,Java,Regex,Parsing,我试图为java表达式创建一个解析器,但由于某些原因,我无法匹配浮点值。我使用的是从 Matcher token = Pattern.compile( "(\\w[\\w\\d]*+)|" + //identifiers as group 1 "((?:(?>[1-9][0-9]*+\\.?[0-9]*+)|(?>\\.[0-9]++))(?:[Ee][+-]?[0-9]++)?)|" + //literal numbers "([^\
Matcher token = Pattern.compile(
"(\\w[\\w\\d]*+)|" + //identifiers as group 1
"((?:(?>[1-9][0-9]*+\\.?[0-9]*+)|(?>\\.[0-9]++))(?:[Ee][+-]?[0-9]++)?)|" + //literal numbers
"([^\\w\\d\\s]*+)" //operators as group 3
).matcher();
这是为了匹配一个标识符、一个浮点值或一个运算符(我仍然需要细化匹配的这一部分,不过稍后会细化匹配的这一部分)。然而,我有一个问题,它在这方面
下面是使用该表达式的代码,该表达式旨在获取所有标识符、数字和运算符,在vars
中注册所有数字,并将所有标识符、每个数字的对应值和标记中的所有运算符按与原始字符串相同的顺序放置
但是,这样做并不成功,因为对于像foo34.78e5bar-2.7这样的输入字符串,结果列表是“[34,A,bar,-,2,B,]”,其中A=-78000.0和B=-0.7。它应该返回“[foo,A,bar,B]”,其中A=3478000,B=-2.7。我相信这可能只是因为它没有将数字的两个部分作为正则表达式的匹配项包含在内,但情况可能并非如此
我已经尝试从正则表达式中删除原子分组和所有格,但是这并没有改变任何事情
LinkedList<String> tokens = new LinkedList<String>();
HashMap<String, Double> vars = new HashMap<String, Double>();
VariableNamer varNamer = new VariableNamer();
for(Matcher token = Pattern.compile(
"(\\w[\\w\\d]*+)|" + //variable names as group 1
"((?:(?:[1-9][0-9]*+\\.?[0-9]*+)|(?:\\.[0-9]++))(?:[Ee][+-]?[0-9]++)?)|" +
//literal numbers as group 2
"([^\\w\\d\\s]*+)" //operators as group 3
).matcher(expression); token.find();){
if(token.group(2) != null) { //if its a literal number, register it in vars and substitute a string for it
String name = varNamer.next();
if (
tokens.size()>0 &&
tokens.get(tokens.size()-1).matches("[+-]") &&
tokens.size()>1?tokens.get(tokens.size()-2).matches("[^\\w\\d\\s]"):true
)
vars.put(name, tokens.pop().equals("+")?Double.parseDouble(token.group()):-Double.parseDouble(token.group()));
else
vars.put(name, Double.parseDouble((token.group())));
tokens.addLast(name);
} else {
tokens.addLast(token.group());
}
}
根据表达式迷你语言的详细信息,它可能接近使用正则表达式的极限。。。或者超越它。即使您成功地进行了“解析”,您也将面临将“组”子字符串映射到有意义表达式的问题
我的建议是采取完全不同的方法。查找/使用现有的表达式库,或者使用ANTLR或Javacc等解析器生成器实现表达式解析。实际上,我这样做的主要原因是为了在项目的后期摆脱更多的正则表达式疯狂,这应该是其中的一部分。听起来你需要更早地摆脱这种疯狂。(有时,我认为Java最好不支持正则表达式…)好吧,我刚刚查看了学校分配EMT的规范,结果发现我甚至不需要浮点支持(我切换到匹配int
s的正则表达式工作得非常好)。不过还是谢谢你。
import java.util.Iterator;
public class VariableNamer implements Iterator<String>{
StringBuffer next = new StringBuffer("A");
@Override
public boolean hasNext() {
return true;
}
@Override
public String next() {
try{
return next.toString();
}finally{
next.setCharAt(next.length()-1, (char) (next.charAt(next.length()-1) + 1));
for(int idx = next.length()-1; next.charAt(idx) + 1 > 'Z' && idx > 0; idx--){
next.setCharAt(idx, 'A');
next.setCharAt(idx - 1, (char) (next.charAt(idx - 1) + 1));
}
if (next.charAt(0) > 'Z'){
next.setCharAt(0, 'A');
next.insert(0, 'A');
}
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}