查找名称中包含奇数字符的记录

Find records with odd characters in names

我有一长串记录是从 excel 文档中导入的,现在已经不存在了。我们开始发现文档中的某些名称包含在导入过程中必须转换的字符。一些例子: ± © Ð € Ù _ l Ì » ñ

我不知道有多少个奇数字符,而且有很多记录。有什么办法可以在记录中搜索其他类似的字符吗?导入是以 JSON 样式格式完成的,因此记录是一个像这个例子一样的长字符串(间隔以便于查看)

{
      "email_address":"fakemail@mail.com",
      "values":{
           "FNAME":"©Johñ",
           "LNAME":"SmÌth»"
      }
}

我正在使用 MSSQL Server 2008 R2,或者如果解决方案更简单的话,我可以使用 C#。感谢任何帮助。

您可以使用 like 和 "not" 以及字符 class:

来查找意外字符
select email_address
from t
where email_address like '%[^a-zA-Z0-9@.]%';

此正则表达式将匹配所有包含 'odd' 字符的行。您不希望被视为奇数的任何其他字符都可以添加到字符 class 以从搜索中排除。

/^.*[^a-zA-Z\s\[\]\{\}'":@.,_].*$/gm

需要注意的是,这会找到在姓名和电子邮件地址中都有效的字符 ,但是 在您的系统中似乎无效,您应该使用以下 LIKE 语句:

WHERE tab.col LIKE '%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2;

这里重要的是 COLLATE Latin1_General_100_BIN2(除非该字段已经在使用二进制排序规则)。但是,如果该字段未使用二进制排序规则,则不在此处为 LIKE 谓词指定一个将丢失 ñ 等字符和其他重音字符,因为它们通常等同于非重音字符(例如 n = ñ).

示例:

SELECT col
FROM (VALUES ('©Johñ'),
             ('{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»"  } }'),
             ('{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones"  } }'),
             ('{  }'),
             ('f_f'),
             ('g-g'),
             ('Johñ f')
     ) tab(col)
WHERE tab.col LIKE '%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2;

使用 COLLATE 子句可以识别 'Johñ f' 行,但如果没有 COLLATE,该行似乎是 "valid".


或者,如果您同时拥有:

  • Unicode 数据(即 NVARCHAR / NCHAR 字段)
  • 一个接受真实世界数据的系统(并且不会错误地拒绝包含非美国英语字符的姓名和电子邮件地址,或将它们转换为美国英语等价物)

然后 T-SQL LIKE 运算符无法工作,因为多种语言的字母种类繁多。在这种情况下,您将需要一个正则表达式,因为它们可以处理字符 类,它们是字符的逻辑分组。当然,T-SQL 中并未原生提供 RegEx,但您仍然可以通过 SQLCLR 获得此功能。您可以找到许多有关如何编写此代码的示例,或者您可以下载 SQL# 库的免费版本(我创建的,但大多数 RegEx 函数 - 以及许多其他函数 - 都是免费的)包含一个 RegEx_IsMatch 函数,可以按如下方式使用:

SELECT tab.col,
       CASE WHEN tab.col LIKE N'%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2
               THEN 1 ELSE 0 END AS [LikeOperator],
       SQL#.RegEx_IsMatch(tab.col, N'[\W-[-\{\} @:",.]]+', 1, N'IgnoreCase')
               AS [RegEx_IsMatch]
FROM (VALUES (N'©Johñ'),
             (N'{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»" } }'),
             (N'{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones" } }'),
             (N'{  }'),
             (N'f_f'),
             (N'g-g'),
             (N'k,k'),
             (N'WIDE'),
             (N'simple-email@place01.co'),
             (N'Johñ f')
     ) tab(col);

Returns:

col                                                                         LIKE    RegEx
-----------------------                                                     -----   ------
©Johñ                                                                           1       1
{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»" } }          1       1
{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones" } }          0       0
{  }                                                                            0       0
f_f                                                                             0       0
g-g                                                                             0       0
k,k                                                                             0       0
WIDE                                                                         1       0
simple-email@place01.co                                                         0       0
Johñ f                                                                          1       0

[\W-[-\{\} @:",.]]+ 模式的意思是:一个或多个字符 ([]+) 是 "non-word" 个字符 (\W) except (-[]) 以下列表都可以: -, {, }, </code>, <code>@:",.