正则表达式从全名中删除首字母
Regex to remove initials from full name
我有像 "D John Livingston" 、 "S. Jennifer Adstan" 这样的名字,我只想从名字中删除首字母,名字中的 "D" 和名字中的 "S."第二个名字。我如何使用 java 正则表达式来做到这一点?
以下代码片段似乎运行良好:
String input = "John O'Connel";
input = input.replaceAll("\b[A-Z]+(?:\.|\s+|$)", "").trim();
System.out.println(input);
John O'Connel
您的问题充满了边缘情况,因为例如首字母可能不止一个字母,并且可能出现在姓名的开头、中间或结尾。我使用模式 \s*[A-Z]+(?:\.|\b)
进行了替换,这似乎至少涵盖了您的示例。另外,我调用 String#trim()
在开头或结尾处对首字母进行一些空白清理。
为此,我会考虑使用字符串 replaceAll()。
那么我们如何设计正则表达式呢?
基本上你需要考虑三种情况:
- 一个。名称开头的单个字母(可选句点),后跟一个
space
- 乙。名称末尾的单个字母(可选句点),前面有一个
space
- C。名称中间的单个字母(可选句点),由
两个 space
对于前两种情况,你不需要留下任何spaces。所以你会匹配一个 space 并将其替换为零 spaces.
最后一种情况,需要留一个space。但是,您可以将其视为 A 或 B,而不是明确处理这种情况,因为它们只会替换两个 space 中的一个,从而为您留下所需数量的 space:1 .
那么我们如何将案例A和案例B结合在一起呢?使用 |
.
的符号
为防止从较大的字母链中抓取单个字母,您可以在未由 space 字符划定的一侧使用单词边框标记 \b
。 (通常对于情况 A 和 B,我会使用 ^
和 $
来明确匹配字符串的开始和结束。但是,由于我们还需要在中间处理情况 C字符串,我们应该改用文字边框标记。)
我们如何表示可选期间?由于句点是特殊字符,必须转义:\.
然后用问号标记为可选:\.?
但是,仍然存在问题,即中间的 A.
name 可能只匹配 A
因为句点也算作单词边框。为了防止这种情况,我们在可选句点 \.?+
.
中添加了所有格量词
将所有这些放在一起,我们的正则表达式将是:(\b[A-Z]\.?+ )|( [A-Z]\.?+\b)
然而,在最后的 Java 字符串中,反斜杠必须被转义,所以在最后的 Java 字符串中,每个 \
将显示为 \
示例代码:
String pattern = "(\b[A-Z]\.?+ )|( [A-Z]\.?+\b)";
String input1 = "MC Hammer I Smash U";
String input2 = "S. Jennifer A. Adstan JR.";
System.out.println(input1.replaceAll(pattern, ""));
System.out.println(input2.replaceAll(pattern, ""));
输出:
MC Hammer Smash
Jennifer Adstan JR.
我有像 "D John Livingston" 、 "S. Jennifer Adstan" 这样的名字,我只想从名字中删除首字母,名字中的 "D" 和名字中的 "S."第二个名字。我如何使用 java 正则表达式来做到这一点?
以下代码片段似乎运行良好:
String input = "John O'Connel";
input = input.replaceAll("\b[A-Z]+(?:\.|\s+|$)", "").trim();
System.out.println(input);
John O'Connel
您的问题充满了边缘情况,因为例如首字母可能不止一个字母,并且可能出现在姓名的开头、中间或结尾。我使用模式 \s*[A-Z]+(?:\.|\b)
进行了替换,这似乎至少涵盖了您的示例。另外,我调用 String#trim()
在开头或结尾处对首字母进行一些空白清理。
为此,我会考虑使用字符串 replaceAll()。
那么我们如何设计正则表达式呢?
基本上你需要考虑三种情况:
- 一个。名称开头的单个字母(可选句点),后跟一个 space
- 乙。名称末尾的单个字母(可选句点),前面有一个 space
- C。名称中间的单个字母(可选句点),由 两个 space
对于前两种情况,你不需要留下任何spaces。所以你会匹配一个 space 并将其替换为零 spaces.
最后一种情况,需要留一个space。但是,您可以将其视为 A 或 B,而不是明确处理这种情况,因为它们只会替换两个 space 中的一个,从而为您留下所需数量的 space:1 .
那么我们如何将案例A和案例B结合在一起呢?使用 |
.
为防止从较大的字母链中抓取单个字母,您可以在未由 space 字符划定的一侧使用单词边框标记 \b
。 (通常对于情况 A 和 B,我会使用 ^
和 $
来明确匹配字符串的开始和结束。但是,由于我们还需要在中间处理情况 C字符串,我们应该改用文字边框标记。)
我们如何表示可选期间?由于句点是特殊字符,必须转义:\.
然后用问号标记为可选:\.?
但是,仍然存在问题,即中间的 A.
name 可能只匹配 A
因为句点也算作单词边框。为了防止这种情况,我们在可选句点 \.?+
.
将所有这些放在一起,我们的正则表达式将是:(\b[A-Z]\.?+ )|( [A-Z]\.?+\b)
然而,在最后的 Java 字符串中,反斜杠必须被转义,所以在最后的 Java 字符串中,每个 \
将显示为 \
示例代码:
String pattern = "(\b[A-Z]\.?+ )|( [A-Z]\.?+\b)";
String input1 = "MC Hammer I Smash U";
String input2 = "S. Jennifer A. Adstan JR.";
System.out.println(input1.replaceAll(pattern, ""));
System.out.println(input2.replaceAll(pattern, ""));
输出:
MC Hammer Smash
Jennifer Adstan JR.