我想帮助解析一些某人的名字。我想取字符串并将其删除,以便只有第一个名字出现在字符串中。
假设我有这样的名字
Mr. John Doe
John Smith.
在这两种情况下,我只想获取字符串的第一个名称并删除所有其他字符。
因此,对于解析后的两个字符串,其中将包含John
我想知道是否有办法用正则表达式解决这个问题。
答案 0 :(得分:6)
你不能这样做。不是因为你已经破坏了他们的名字而烦恼了一些人。你无法区分John Paul Doe(名字“John”,中间名“Paul”,姓氏“Doe”),John Joseph Brown(“Joseph”或“Joe”的答案,但只使用“John”政府形式)和约翰保罗史密斯(名字“约翰保罗”,并讨厌缩短它。)
阅读Falsehoods Programmers Believe About Names。
然后再读一遍,这次接受,是的,世界上95%的人口都有 一个与你的名字完全不同的想法。 (如果你是中国人,则为80%。)
你能做的最多就是截断空格,也许还有一些像“先生”这样的“安全”前缀 - 我甚至不会这样做(如果人们不好意思写“先生”,他们可能会喜欢它有)。
s/^\s+//; s/\s+$//; # trim whitespace at each end
s((\s+))( # trim embedded whitespace
$1=~/[^\x{a0}]/ ? # breakable?
" " : "\x{a0}")ge;
答案 1 :(得分:1)
答案 2 :(得分:1)
这是一个匹配两种情况的简单正则表达式
/^(?:\w+\.)?\s*(\w+).*$/
// $1 = John
你可以像这样建立起来:
\w+\.
至少有一个单词字符后跟一个点(用于名称前缀)
(\w+\.)?
该群组可以出现一次或根本不出现
(?:\w+\.)?
小组没有捕获(我们不需要它)
^(?:\w+\.)?
^表示整个字符串的开头(因此该组是其中的第一个内容)
^(?:\w+\.)?\s*
此前缀组后面可以跟任意数量的空格(或无)
^(?:\w+\.)?\s*(\w+)
比名称(由至少一个单词字符组成)组跟在组后面
最后^(?:\w+\.)?\s*(\w+).*$
.*
与其他字符匹配,直到字符串$
答案 3 :(得分:0)
您想接受多少种不同的格式?
这是适用于你发布的两个的一个:
/(?<=((Mr\.|Mrs\.)\s+)?)([a-zA-Z]+)/
答案 4 :(得分:0)
我认为这会起作用
my $nameFull = 'Mr. John Doe';
my $nameFirst = $1 if $nameFull =~ /(?:\s|^)(?!(?:mr|mr?s|miss|dr|prof)(?![a-z]))([a-z]+)/i;
说明:
/
... /i
不区分大小写的正则表达式的开头和结尾
(?:\s|^)
确保我们处于空格字符或字符串的开头。(?!
... )
确保在第一个名称的开头不匹配
(?:mr|mr?s|miss|dr|prof)
缩写列表(r?
表示可选r
,因此符合Ms
和Mrs
)(?![a-z])
确保缩写后面没有其他字母,因为drake
是一个以dr
开头的名称(
... )
将其捕获到$1
[a-z]+
连续多少封信。假设至少有一个。