Java 8查找并替换匹配的字符串 [英] Java 8 find and replace matching string(s)
问题描述
我试图在 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屋!