Java 8查找并替换匹配的字符串

我试图在errorMessage messages.properties中找到一个字符串,如果errorMessage有字符串我需要用相应的值替换它

我有messages.properties如下

 inv_date=INVOICE DATE inv_id=INVOICE NUMBER cl_id=CLIENT ID lf_matter_id=LAW FIRM MATTER ID inv_total_net_due=INVOICE TOTAL (inv_start_date|invoice start date)=BILLING START DATE (inv_end_date|invoice end date)=BILLING END DATE inv_desc=INVOICE DESCRIPTION units=LINE ITEM NUMBER OF UNITS discount_amount=LINE ITEM ADJUSTMENT AMOUNT total_amount=LINE ITEM TOTAL (charge_date|charge date)= LINE ITEM DATE acca_task=LINE ITEM TASK CODE acca_expense=LINE ITEM EXPENSE CODE acca_activity= LINE ITEM ACTIVITY CODE (tk_id|time keeper id)=TIMEKEEPER ID charge_desc=LINE ITEM DESCRIPTION lf_id=LAW FIRM ID (BaseRate|Rate|tk_rate)=LINE ITEM UNIT COST tk_level=TIMEKEEPER CLASSIFICATION cl_matter_id=CLIENT MATTER ID 

我的errorMesage可以有任何(左侧)字符串,我需要用右侧字符串值替换它

以下是几个示例错误消息

 String errorMesage1 = "Line 3 : Could not parse inv_date value" String errorMesage2 = "Line : 1 BaseRate is a required field" 

下面是我的方法,它会转换错误信息

 public static String toUserFriendlyErrorMessage(String message) { ResourceBundle rb = ResourceBundle.getBundle("messages"); for(String key : rb.keySet()){ String header = rb.getString(key); if(message.contains(key)) { return message.replaceAll(key, rb.getString(key)); } } return message; } 

下面是预期的输出:对于errorMessage1,它工作正常

 System.out.println(toUserFriendlyErrorMessage(errorMessage1)); ==> Line 3 : Could not parse INVOICE DATE value 

但是对于errorMessage2它不起作用。 它没有用LINE ITEM UNIT COST取代BaseRate

 System.out.println(toUserFriendlyErrorMessage(errorMessage2)); ==> Line : 1 BaseRate is a required field 

有没有办法找到多个字符串的出现并用相应的值替换它?

例如:Find (BaseRate|Rate|tk_rate)并用LINE ITEM UNIT COST替换字符串

另外我想知道这种方法可以在java 8中进一步简化吗?

我认为你应该重新考虑你的设计并使用单独的密钥来获得几个“别名” – 或者甚至更好:没有别名,每个替换只有一个密钥。 问题是这些属性文件中的键不应该包含空格 – 是否是parantheses – 因此文件未正确解析。 如果您打印密钥,您将看到它们在第一个空格处被截断,例如(inv_start_date|invoice start date)变为(inv_start_date|invoice

当然,这也意味着,即使您将这些“别名”拆分为单独的键,也不能拥有invoice start date等密钥,因为它仍然包含空格并且无法正确解析。

可以将这些替换放入Java源代码中的regualr Map

 static Map replacements = new HashMap<>(); static { replacements.put("inv_date", "INVOICE DATE"); replacements.put("(BaseRate|Rate|tk_rate)", "LINE ITEM UNIT COST"); // ... more stuff ... } 

或者手动解析文件,将字符串拆分为=并将它们放入Map

因为像(BaseRate|Rate|tk_rate)这样的键实际上是有效的正则表达式,所以你可以使用replaceAll替换它们的所有变体。 如果它们不包含在字符串中,则replaceAll将不执行任何操作,因此contains检查不是必需的。

 public static String toUserFriendlyErrorMessage(String message) { for (String key : replacements.keySet()) { message = message.replaceAll(key, replacements.get(key)); } return message; } 

输出示例:

 Line 3 : Could not parse INVOICE DATE value Line : 1 LINE ITEM UNIT COST is a required field 

或者,如果你想使用一些“Java 8魔法”,你可以使用reduce ,但就个人而言,我认为循环更具可读性。

  return replacements.keySet().stream() .reduce(message, (s, k) -> s.replaceAll(k, replacements.get(k))) .toString();