【问题标题】:replaceAll and regex groups‽replaceAll 和正则表达式组‽
【发布时间】:2020-03-12 09:44:34
【问题描述】:

我最近完成了以下编程练习:Acronym Generator

声明是:

几乎在每家公司中,每个员工都有一个特定的首字母缩写词,其中包含 他的名字和姓氏的第一个字符。

你的任务是编写一个生成首字母缩略词的首字母缩略词生成器 对于给定的名称。您不必关心重复的首字母缩略词 (其他人会为你做这件事)。请注意,名称可以在 大写或小写。首字母缩写词应始终为大写。

通常,首字母缩写词始终是您的第一个字母的第一个字母,而 姓氏的第一个字母大写。

例如:

Thomas Meyer => TM

martin schmidt => MS

在你的公司里,只有最多两个第一的人工作 名字。如果一个人有两个名字,他们可能会用一个 破折号。

Jan-Erich Schmidt => JES Jan Erich Mueller => JEM

姓氏也可以用破折号连接。没有人可以拥有超过 两个姓氏。

Paul Meyer-Schmidt

在德国,有些姓氏的前导词是“von”。 这应缩写为小写“v”:

Paul von Lahnstein => PvL

Martin von Lahnstein-Meyer => MvLM

我已经完成了练习,我正在尝试理解其他人的答案。我找到了一个使用replaceAll 和正则表达式的。可以看这个解决方案in this link.

public class AcronymGenerator {
  public static String createAcronym(String lastName, String firstName) {
    firstName = firstName.toUpperCase().replaceAll("(.)([A-Z])*([-| ])?(.)?(.)*", "$1$4");
    String von = lastName.toLowerCase().replaceAll("^((v)(on ))?(.)*", "$2");
    lastName = lastName.toUpperCase().replaceAll("(VON )?(.)([A-Z])*([-| ])?(.)?(.)*", "$2$5");
    return firstName+von+lastName;
  }
}

我猜他所做的是将名字替换为大写字母的首字母,von 替换为 v,姓氏替换为大写字母的首字母。但是,我不明白在 replaceAll 中使用时,正则表达式组是如何工作的

您能解释一下 replaceAll() 如何与正则表达式组一起工作吗?我想了解它是如何工作的:

replaceAll("(.)([A-Z])*([-| ])?(.)?(.)*", "$1$4");
replaceAll("^((v)(on ))?(.)*", "$2");
replaceAll("(VON )?(.)([A-Z])*([-| ])?(.)?(.)*", "$2$5");

我也读过: Java: Understanding the String replaceAll() method What is a non-capturing group in regular expressions? How to Extract people's last name start with "S" and first name not start with "S"

【问题讨论】:

  • 我只是想知道如何在致电createAcronym(String lastName, String firstName) 之前将全名正确拆分为名字和姓氏。当然可以,只是在给定的规则下,这似乎并不简单。
  • @OleV.V.如果您要求用户在一个字段中输入名字并在另一个字段中输入姓氏,这非常简单。

标签: java regex string replace


【解决方案1】:

在正则表达式中,() 括号用于定义。如果括号内的第一个字符是?,则为非捕获组1,否则为捕获组

1) 除了(?<name>X) 是一个命名的捕获组。

示例: A(FOO)B 将匹配字符串 "AFOOB" 并将捕获字符串 "FOO"A(?:FOO)B 将匹配字符串 "AFOOB" 并且不会捕获任何内容。

由于一个正则表达式可以有多个捕获组,它们由位置标识,从第一个 ( 开始是捕获组1

示例: A(X)B(?:Y)C(Z) 将匹配字符串 "AXBYCZ" 并将 捕获 "X" 作为组 1,"Z" 作为组 2。非捕获组不计算在内。

所以,在你的例子中:

replaceAll("(.)([A-Z])*([-| ])?(.)?(.)*", "$1$4");
            ↑  ↑       ↑       ↑   ↑
            1  2       3       4   5

如果一个组是可选的(直接在这里,或者在一个更大的可选组内),那么当通过在Matcher 上调用group(n) 检索时捕获的值为空,或者在使用@987654337 引用时为空字符串替换值中的 @ 语法(如此处所示)。

它上面的正则表达式实际上捕获了太多,并且在字符类中错误地使用了|,最好写成:

replaceAll("(.)[A-Z]*[- ]?(.)?.*", "$1$2");
            ↑             ↑
            1             2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多