当前位置: 首页 > 面试题库 >

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

何峰
2023-03-14
问题内容

我试图从找到字符串messages.properties中的errorMessage,如果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它不起作用。它不会替换BaseRateLINE ITEM UNIT COST

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

有没有办法找到多个字符串的出现并将其替换为其对应的值?

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

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


问题答案:

我认为您应该重新考虑设计并为几个“别名”使用单独的密钥-
甚至可能更好:根本没有别名,每次替换只有一个密钥。问题在于这些属性文件中的键不应包含空格(无论是否带括号),因此无法正确解析文件。如果您打印按键,您将看到它们在第一个空格处被截断,例如(inv_start_date|invoice start date)变为(inv_start_date|invoice

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

可以 将这些替换项放入MapJava源代码中的regualr 中:

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

并且由于像这样(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();


 类似资料:
  • 我从一个wordpress博客获得RSS提要,在那里我得到字符串中的缩略图。下面是我得到的示例提要 我需要移除”?从图像源调整大小=50,50"。但问题是我不能在我的代码中硬编码,因为大小可能不一样。此外,属性放置的顺序可能会改变 我怎样才能简单地删除任何与此模式匹配的内容,以便始终获得输出 提前谢谢

  • 问题内容: 我想同时执行完全的单词匹配和部分的单词/子字符串匹配。例如,如果我搜索“男士剃须刀”,那么我应该能够在结果中找到“男士剃须刀”。但是,如果我搜索“剃须刀”,那么在结果中我也应该能够找到“剃须刀”。我使用以下设置和映射: 索引设置: 对应: 插入记录: 查询: 1.按完全匹配的词组进行搜索- >“男式” 上面的查询在返回结果中返回“男士剃须刀”。 2.按部分单词匹配搜索- >“ en’s

  • 我有两个文本文件,并用第二个文件中的实际匹配项替换XXX占位符-按照第二个文件中给出的顺序。 第一个文本是一个文件,在一行中有多行和多个占位符。 欧盟由以下国家组成:XXX、XXX、XXX、XXX、XXX。。。。欧盟内最大的三个国家是XXX,XXX,XXX。 第二个文件是每行一个匹配的列表: 波兰荷兰丹麦西班牙意大利德国法国 我想把它替换如下: 欧洲联盟由下列国家组成:波兰、荷兰、丹麦、西班牙、意

  • 如何读取文件并从json转换为字符串?示例:我的文件编号为。json[“23423423”,“234234234”,“53453453”] 我想要的是:String numbers=“'23423423','234234234','53453453'”;

  • 问题内容: 我正在尝试在文件中找到一行并将下一行替换为特定值。我尝试使用sed,但似乎不喜欢\ n。还可以怎么做? 该文件如下所示: 我想将其更改为此 这是我尝试过的: 问题答案: 这可能对您有用(GNU sed): 取反前一个地址(regexp)并中断所有处理,结束sed命令,打印当前行,然后将下一行读入模式空间,将当前行更改为命令后的字符串。

  • 问题内容: 我想用php代替完整的单词 示例:如果我有 我用 新文本应如下所示 新hello1您好,Helloz PHP返回 NEW hello1 hello,NEWz 谢谢。 问题答案: 您要使用正则表达式。该单词边界匹配。 如果包含UTF-8文本,则必须添加Unicode修饰符“ u”,以便不会将非拉丁字符误解为单词边界: