Java 8查找并替换匹配的字符串 [英] Java 8 find and replace matching string(s)

查看:1639
本文介绍了Java 8查找并替换匹配的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to find a string from messages.properties in an errorMessage and if the errorMessage has the string I need to replace it with corresponding value

我有 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 可以有任何(左侧)字符串,我需要用右侧字符串值替换它

My errorMesage can have any of the (left side)string and I need to replace it with right side string value

下面是几个示例错误消息

Below are couple of sample error messages

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

下面是我的方法转换错误消息

below is my method which conversts the error message

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;

}

以下是预期输出:
for errorMessage1它工作正常

Below is the expected output: for errorMessage1 it works fine

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

但对于errorMessage2,它无效。它不会替换 BaseRate LINE ITEM UNIT COST

But for errorMessage2 its not working. It doesnt replace BaseRate with LINE ITEM UNIT COST

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

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

Is there a way to find the occurance of multiple strings and replace it with its corresponding value?

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

For example: Find (BaseRate|Rate|tk_rate) and replace the string with LINE ITEM UNIT COST

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

Also am wondering can this method simplified further in java 8?

推荐答案

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

I think you should reconsider your design and use individual keys for the several "aliases" - or probably even better: No aliases at all and just one key per replacement. The problem is that the keys in those properties files are not supposed to contain spaces -- parantheses or not -- so the files are not parsed correctly. If you print the keys, you will see that they are truncated at the first space, e.g. (inv_start_date|invoice start date) becomes (inv_start_date|invoice.

当然,这也意味着,即使您将这些别名拆分为单独的密钥,您也不能拥有发票开始日期等密钥,因为它仍然包含空格,不会被正确解析。

Of course, this also means that, even if you split those "aliases" into separate keys, you can not have keys like invoice start date, as it still contains spaces and will not be parsed correctly.

可以将这些替换放入一个regualr Map 在您的Java源代码中:

You could just put those replacements into a regualr Map in your Java source code:

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

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

Or parse the file manually, splitting the strings at = and putting them into a Map.

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

And since keys like (BaseRate|Rate|tk_rate) are in fact valid regular expressions, you can just use replaceAll to replace them in all their variants. If they are not contained in the string, replaceAll will just do nothing, so the contains check is not really necessary.

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 magic,你可以使用 reduce ,但就我个人而言,认为循环更具可读性。

Or, if you want to use some "Java 8 magic", you could use reduce, but personally, I think the loop is more readable.

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

这篇关于Java 8查找并替换匹配的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆