java - 如何用犀牛脚本处理百分比?
问题描述
我正在制作一个计算器应用程序,它基本上构建了一个使用 rhino 来处理方程的字符串。但问题是我找不到处理百分比的方法。它不接受 % 符号。
我需要用“?/ 100 *?”替换它的所有实例 在字符串中,其中 ?st 是百分比之前的数字,而 ?nd 与 percent 一起使用。
例如 "5 + 3% + 2" --> "5 + 5/100*3 + 2" 。
问题是我不知道可以预期什么样的数字,它甚至可能是 (5+4)-(3+1)% 或长小数。由于百分比在字符串中,因此我不使用变量。这是下面的示例(按下等于按钮时调用的方法):
btnEquals.setOnClickListener(v -> {
process = tvInput.getText().toString();
process = process.replaceAll("%", "?/100*?"); // this is the problem line
rhinoAndroidHelper = new RhinoAndroidHelper(this);
context = rhinoAndroidHelper.enterContext();
context.setOptimizationLevel(-1);
String finalResult = "";
try {
Scriptable scriptable = context.initStandardObjects();
finalResult = context.evaluateString(scriptable, process, "javascript", 1, null).toString();
} catch (Exception e) {
finalResult = "0";
}
tvOutput.setText(finalResult);
tvInput.setText("");
});
我正在使用这个助手库:https ://github.com/F43nd1r/rhino-android
我没有使用犀牛的经验,所以我不知道是否有一个简单的解决方案。我认为唯一的解决方案是构建一个复杂的字符串解析方法,该方法将检查百分比之前的内容并重新格式化它。关于犀牛还有其他方法吗?
这是我写的一个字符串格式化方法。它可以正确处理任何包含单个 % 的方程:
private void format(String s){
int newIndex = s.indexOf("%");
int nextIndex = newIndex;
StringBuilder percentage = new StringBuilder();
StringBuilder value = new StringBuilder();
char character;
String result = "";
StringBuilder newProcess = new StringBuilder(s);
boolean done = true;
boolean firstPartDone = false;
boolean firstSymbol = false;
while(done){
while (!firstPartDone){
if(nextIndex == 0){
done = false;
}
nextIndex--;
character = s.charAt(nextIndex);
if(character == '+' | character == '/' | character == '*' | character == '-'){
firstPartDone = true;
}else{
percentage.insert(0, character);
}
}
if(nextIndex == 0){
done = false;
}
character = s.charAt(nextIndex);
if(character == '+' | character == '/' | character == '*' | character == '-'){
if(!firstSymbol){
// value.insert(0, character);
nextIndex--;
firstSymbol = true;
}else{
done = false;
}
}else{
value.insert(0, character);
nextIndex--;
}
}
// percentage.append("%");
System.out.println(percentage);
System.out.println(value);
result = value + "/100*" + percentage;
String percent = percentage.toString();
String percentToReplace = percent.concat("%");
String finalString = newProcess.toString();
finalString = finalString.replace(percentToReplace, result);
process = finalString;
}
上述方法的问题在于它仍然缺少检测和处理括号的支持,例如 (5+4)-(4+2)% 。我可以写。但是当有 2% 存在时它会出错。例如: 5+10%-4+50% 将变为 5+ 5/100 10 - 4 + 4/100 50 。由于某种原因,上述等式最终会产生不好的结果。有必要包含括号等。我只是希望有一种更简单的方法。
解决方案
Rhino is a javascript engine without DOM support. If vanilla javascript can do it, Rhino can do it.
Since the meaning of % is context dependent, I don't think there's any easy way to use Rhino (vanilla javascript) to solve it. You need to parse it or find a library that will parse it. You can use javascript libraries with Rhino https://groups.google.com/g/mozilla.dev.tech.js-engine.rhino/c/fS8KQelY0bs
FYI - Baleudung says Rhino is obsolete and Nashorn is faster.
Original response:
Try using process = process.replaceAll("%", "/100");
replaceAll accepts a regex and every time the regex is found it replaces it with exactly the replacement value. In your first example it will be changed it to 5+3?/100*?+2
, which is not valid javascript
/
has priority over +
so it will adjust the values to percentages before adding the numbers.
Depending on how you want the calculator to work, this may have issues when multiple % are used. For example, 5+3%% or (1-3)+(1+2%)%. You need to decide if you want 3%% to mean 3/100/100 or not. If you want to reject %%, you could handle this in the input stage, by not letting %% be entered or after the input stage by parsing it to turn %% into %.
推荐阅读
- android - 动画在启动时崩溃的活动
- django - wagtail 和 elasticsearch 不支持 __icontains?
- javascript - 下拉活动状态是 jquery/javascript 中父 div 的问题
- javascript - 继承和原型链如何在 JS 中工作
- vb.net - Visual Studio VB winform 样式/主题已更改?Texbox 现在有阴影?
- symfony - 如何在 Symfony 2.8 中手动设置路由器区域设置
- python - 在python中滚动数组
- excel - 如何使用 VBA 创建 Excel 宏来粘贴特定公式?
- computer-vision - 人脸界标检测的人脸边界框
- python - [Postgres][Python] - 为什么打印数据库中的值,但返回没有?如何从数据库中返回字符串列表?