句読点を含む列から値をプルできる[0-9]
および[a-z]
パターンに相当するT-SQLはありますか?
例えば:
Create Table #Test
(
Value VarChar(10)
)
Insert Into #Test
Values ('123a'), ('456b'), ('12ABC'),('AB!23'),('C?D789')
Select *
From #Test
Where Value like '[0-9][0-9][0-9][a-z]'
これは、最初の3文字が0から9までの数字で、最後の文字がaからzまでの文字になる値を返すため、123a
や456b
などを返しますが、aは返しません。 12ABC
の値。
[0-9]
は数字を表し、[a-z]
は文字を表すので、AB!23
およびC?D789
を返すので、句読点に相当するものがあるかどうかを知りたいです。
正規表現を使用できる場合、^[a-zA-Z0-9]*$
という表現を使用して、文字列内の英数字に一致させることができます。
Where Value like '^[a-zA-Z0-9]*$'
これに相当するSQLはありますか?
RegExで実行できるこのようなことは知っていますが、T-SQLでそれが必要です。このサーバーにカスタムアセンブリを読み込むことができないため、正規表現を使用できません。
実際の列はvarchar(200)です。照合順序は、Latin1_General_CI_ASです。 SQL Server 2012 Standard Editionを使用しています。
正確なソリューションに到達する際の最大の困難は、どの文字を含める(または除外するか、どちらの方向が操作にとって意味があるか)を正確に定義することです。意味:
VARCHAR
/ASCII dataまたはNVARCHAR
/Unicode data?について話しているのですか?ASCII dataの句読文字のリスト照合に依存するコードページに依存します(この質問では、ASCII data)を扱っています)。Latin1_General_CI_AS
を扱っています).
、,
、;
、:
など)だけを意味するのか、それとも非英数字を意味するのか?¢
、£
、¥
などの通貨記号はどうですか?©
や™
などの記号はどうですか?Â
、É
、Ñ
、ß
、Þ
などの英語以外の文字が含まれていますか?Æ
/æ
文字はどうですか?予想される動作をわかりやすくするために、次のクエリは、Latin1文字セットのすべての256文字(つまり、コードページ1252)と、@ Shaneisの2つのバリエーション 提案されたソリューション がどのように動作するかを示します。最初のフィールド(Latin1_General_CI_AS
とラベルが付いている)は、@ Shaneisが提案したLIKE
句を示し(執筆時点)、2番目のフィールド(Latin1_General_100_BIN2
とラベルが付いている)は、照合順序をオーバーライドして、バイナリ照合順序を指定します(つまり、末尾が_BIN2
である照合順序。_BIN
照合順序は廃止されているため、_BIN2
バージョンへのアクセス権がある場合は使用しないでください)。現在の照合順序では大文字と小文字が区別されないため、大文字を除外するためにA-Z
の範囲を追加する必要もありました。
;WITH nums AS
(
SELECT TOP (256) (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) AS [Decimal]
FROM [master].[sys].[all_objects]
)
SELECT nm.[Decimal],
CHAR(nm.[Decimal]) AS [Character],
CASE WHEN CHAR(nm.[Decimal]) LIKE '%[^a-z0-9]%'
THEN 'x' ELSE '' END AS [Latin1_General_CI_AS],
CASE WHEN CHAR(nm.[Decimal]) LIKE '%[^a-z0-9A-Z]%' COLLATE Latin1_General_100_BIN2
THEN 'x' ELSE '' END AS [Latin1_General_100_BIN2]
FROM nums nm;
[〜#〜]更新[〜#〜]
[〜#〜] if [〜#〜]「句読点」(「通貨記号」ではなく)として分類されている文字を本当に探している、「数学記号」など)、および[〜#〜] if [〜#〜]SQLCLRの使用/カスタムアセンブリのロード(SQLCLRは、 SQL Server 2005では、(Azure SQL Database V12がSAFE
アセンブリをサポートしているため、特に)これを許可しない良い理由にまだ遭遇していないため、次のことができます。正規表現を使用しますが、ほとんどの人が推測する理由ではありません。
正規表現を使用してより機能的な文字範囲を構築するのではなく、\w
(「Word」文字を意味する)などを使用するのではなく、フィルタリングする文字のUnicodeカテゴリを指定できます。いくつかの定義されたカテゴリがあります:
https://www.regular-expressions.info/unicode.html#category
「InBengali」、「InDingbats」、「InOptical_Character_Recognition」など、フィルタリングするUnicodeブロックを指定することもできます。
https://www.regular-expressions.info/unicode.html#block
SQL Server用のRegEx関数を作成する例は多数ありますが(ほとんどの例はSQLCLRのベストプラクティスに従っていません)、無料の SQL# ライブラリ(私が作成したもの)をダウンロードできます。次のようにスカラーRegEx_IsMatch関数を使用します。
SQL#.RegEx_IsMatch(Unicode-String-Expression, N'\p{P}', 1, NULL)
\p{P}
式は、\p
= Unicodeカテゴリ、および{P}
=すべての句読点を意味します(「コネクタ句読点」などの特定の種類の句読点とは対照的)。また、「句読点」カテゴリには、すべての言語の句読点がすべて含まれています。 Unicode.orgサイトの完全なリストは、次のリンクから参照できます(現在、そのカテゴリには717のコードポイントがあります)。
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AGeneral_Category%3DPunctuation%3A%5D
上記のテストクエリの更新バージョン。\p{P}
を使用したSQL#.RegEx_IsMatchを使用する別のフィールドと、3つすべての結果が含まれます。コードページ1252の256文字すべて(つまり、Latin1_General)のテストは、Pastebin.comの次の場所に投稿されています。
文字のタイプをフィルタリングするためのT-SQLクエリと結果
[〜#〜]更新[〜#〜]
関連するディスカッションで以下が言及されました:
アクセント記号付きの文字について良い点を説明しました。世界中のホテル名で、名前にアクセント記号付きの文字が含まれています。私の問題では、これらを有効なアルファ文字として分類したいと思います。
この場合:
Latin1文字セット/コードページに含まれる英語以外の11文字があり、a-z
の範囲と一致しません。それらはð Ð Þ þ œ Œ š Š ž Ž Ÿ
です。これらはワイルドカードに追加する必要があります。現時点では必要ありませんが、A-Z
を追加してもパターンは大文字と小文字を区別する照合で同じように機能します。最終結果は次のとおりです。LIKE '%[^a-zA-Z0-9ðÐÞþœŒšŠžŽŸ]%'
このデータに「世界中のホテル名」が含まれる可能性があることを考慮して、保存できるように、列のデータ型をNVARCHAR
に変更することを強くお勧めしますすべての言語のすべての文字。これをVARCHAR
として維持すると、ラテン語ベースの言語しか表現できず、ラテン語に関連する追加の文字を提供する6つの補足的なUnicodeカテゴリを完全に表すことができないため、最終的にデータ損失のリスクが非常に高くなります。
私はこれを少し単純化しすぎているかもしれませんが、英数字の値が削除されたときに句読点が残っていると言う場合、次は非英数字を含む文字列を検索します。
Create Table #Test
(
Value VarChar(10)
)
Insert Into #Test
Values ('123a'), ('456b'), ('12ABC'),('AB!23'),('C?D789')
-- Original
Select *
From #Test
Where Value like '[0-9][0-9][0-9][a-z]'
-- Non Alpha-numeric
SELECT * FROM #Test WHERE Value LIKE '%[^a-z0-9]%';
DROP TABLE #Test;