我有一串混合数据,一些单词和数字。数字可以是整数,整数的比率,也可以是整数前的百分号。我试图在程序运行期间(而不是数据库)将这些信息存储在Map中(可能是另一种类型的对象,如果有意义的话)。撇开百分号,剩下的数据被解析好了。我总是可以期待这些数据是以冒号形式存在的。如何将Map <String,String>更改为Map <String,Ratio>,比率为x/y
正确的输出(制表符给出滑稽缩进):
AB: 272/272 CD: 204/529 EFGH: 105 HIJKL: 105 MN: 0 OPQ: 0%
AB 272/272
HIJKL 105
CD 204/529
MN 0
EFGH 105
OPQ 0%
-----------
AB 272/272
CD 204/529
HIJKL 105/1
MN 0/1
EFGH 105/1
OPQ 0/1
第一打印与Map<String,String>
,第二个是用Map<String,Ratio>
。如果有比我自制比例更好的选择,我会很乐意使用它。
笨拙的代码,是的,过度使用静态的,只是为了容易复制/粘贴:
package regex;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.System.out;
class Ratio {
private int numerator;
private int denominator;
private Ratio() {
}
public Ratio(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public int getNumerator() {
return numerator;
}
public int getDenominator() {
return denominator;
}
public String toString() {
return numerator + "/" + denominator;
}
}
public class Ratios {
private static String line = "AB: 272/272 CD: 204/529 EFGH: 105 HIJKL: 105 MN: 0 OPQ: 0%";
private static Map<String, String> rawMapStringToString = new HashMap<>();
private static Map<String, Ratio> mapStringToRatio = new HashMap<>();
public static void main(String[] args) {
out.println(line);
populateMap();
printMap(rawMapStringToString);
out.println("-----------");
ratios();
printMap(mapStringToRatio);
}
private static void populateMap() {
Pattern pattern = Pattern.compile("(\\w+): +(\\S+)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
rawMapStringToString.put(matcher.group(1), matcher.group(2));
}
}
private static void printMap(Map<?, ?> m) {
for (Map.Entry<?, ?> e : m.entrySet()) {
String key = e.getKey().toString();
String val = e.getValue().toString();
out.println(key + "\t\t" + val);
}
}
private static void ratios() {
Pattern pattern = Pattern.compile("(\\d+)/(\\d+)");
Pattern p2 = Pattern.compile("(\\w+)");
Matcher m2;
int num, den;
Ratio ratio = null;
for (Map.Entry<String, String> e : rawMapStringToString.entrySet()) {
ratio = null;
num = 0;
den = 1;
Matcher matcher = pattern.matcher(e.getValue());
while (matcher.find()) {
num = Integer.parseInt(matcher.group(1));
den = Integer.parseInt(matcher.group(2));
ratio = new Ratio(num, den);
}
if (ratio == null) {
m2 = p2.matcher(e.getValue());
while (m2.find()) {
num = Integer.parseInt(m2.group());
den = 1;
ratio = new Ratio(num, den);
}
}
mapStringToRatio.put(e.getKey(), ratio);
}
}
}
我只是在寻找一种存储这些数据的好办法。当然,百分比可以表示为x/y的比率,只需将分母改为100即可。暂时搁置一下,Map是一个不错的选择?
ratios
方法和整体正则表达式似乎很脆弱,尴尬和困难(对我来说),但我不确定如何改进代码。保持Ratio
类几乎不变,我该如何改进ratios
方法,该方法填充了mapStringToRatio
?
感谢您的反馈。是的,我将使用这些数据,如果不清楚,请原谅。它就像示例代码一样是静态的。我更加关注重复的正则表达式,并认为可能有一种方法可以用一个正则表达式一步完成。但是,也许需要一些难以维护的巨大的,难以理解的(对我来说)正则表达式。这就是'if(ratio == null)'这条线,看起来很尴尬或令人费解。 – Thufir
我添加到我的答案一个解决方案与一个正则表达式使用命名组。这使它更清晰可读!我希望这有助于! – visola
花了我一会儿才弄清楚'matcher = pattern.matcher()'是一种if语句。我在下面添加了我自己的答案。 – Thufir