我搜索并尝试了几种不同的方法来使用 REGEXP_LIKE()
评估这些名称模式在 Oracle select 语句中。如果我的表达式计算结果为真,我只是将原始列值放入各种人为的列中,这些列基于它满足的条件为真。所以,我只是想获得第一个,但它不起作用!
我在数据库中有一列姓名,这些姓名是自由格式输入到一个字段中的。它们可以是:
FirstName LastName
FirstName MiddleInitial LastName
FirstName MiddleInitial. LastName
LastName, FirstName MiddleInitial.
这涵盖了大多数情况。但我只是想评估第一个模式,如果它与 FirstName LastName 匹配。
所以,我试过:
(CASE Expressions)
-
REGEXP_LIKE(name, '\S+\s?\S+')
并且对所有人都适用,即使是名称中有 2 个空格的名称,例如 FirstName MiddleInitial LastName。 -
REGEXP_LIKE(name, '[^\s]+\s?[^\s]+')
并且对所有人来说都是正确的,我认为 [^\s] 会排除允许在名字和姓氏之间的任何地方使用空格。 -
REGEXP_LIKE(name, '[A-Z,a-z]+" "?[A-Z,a-z]')
并为所有错误(尝试使用 Posix 版本而不是 Perl 影响)。
我可能也尝试过大约 10 种其他变体,但我不记得或把它们都打出来了。我希望有人可以让我开始处理 FirstName LastName 的第一个匹配案例,然后我会“得到它”并从那里开始!
最佳答案
FirstName LastName
将匹配 ^[^[:blank:]]+[[:blank:]]+[^[:blank:]]+$
^
从字符串的开头[^[:blank:]]+
一个或多个非空白[[:blank:]]+
后跟一个或多个blank[^[:blank:]]+
后接一个或多个非空白$
到字符串结尾
从 Oracle 11g 开始,您可以使用 Perl-influenced Extensions in Oracle Regular Expressions .因此,您可以使用更简洁的模式 ^\S+\s+\S+$
话虽如此,您可能必须使用类似的方式规范化您的数据:
with testdata as (select 'James T. Kirk' ff from dual union all
select 'Montgomery Scott' from dual union all
select 'Riker, William T.' from dual union all
select 'Miles O''Brien' from dual union all
select 'Harcourt F Mudd' from dual),
patterns as (select '^((\S+)\s+(\S+))$' s, '\2' fn, '' mi, '\3' ln from dual union all
select '^((\S+)\s+(\S)\s+(\S+))$', '\2' fn, '\3' mi, '\4' ln from dual union all
select '^((\S+)\s+(\S)\.\s+(\S+))$', '\2' fn, '\3' mi, '\4' ln from dual union all
select '^((\S+),\s+(\S+)\s+(\S)\.)$', '\3' fn, '\4' mi, '\2' ln from dual)
select regexp_replace(ff, s, fn) "first name",
regexp_replace(ff, s, mi) "middle initial",
regexp_replace(ff, s, ln) "last name"
from testdata cross join patterns
where regexp_like(ff, s)
请根据您的实际数据调整模式。参见 http://sqlfiddle.com/#!4/d41d8/39008一个活生生的例子。
关于Oracle 数据库中的 REGEXP 挫败感,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27555890/