Apakah ada T-SQL yang setara dengan [0-9]
dan [a-z]
pola yang akan membiarkan saya menarik nilai dari kolom yang berisi tanda baca?
Sebagai contoh:
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]'
Ini akan mengembalikan nilai di mana 3 karakter pertama adalah angka antara 0 dan 9 dan karakter terakhir akan menjadi huruf antara a dan z, jadi akan mengembalikan hal-hal seperti 123a
dan 456b
tetapi tidak akan mengembalikan nilai 12ABC
.
Saya ingin tahu apakah ada yang setara dengan tanda baca seperti [0-9]
untuk angka dan [a-z]
untuk huruf sehingga akan kembali AB!23
dan C?D789
?
Jika saya bisa menggunakan ekspresi reguler, saya bisa menggunakan ekspresi ^[a-zA-Z0-9]*$
untuk mencocokkan karakter alfanumerik dalam string.
Where Value like '^[a-zA-Z0-9]*$'
Apakah ada persamaan SQL untuk ini?
Saya tahu hal semacam ini yang dapat dilakukan di RegEx tetapi saya membutuhkannya dalam T-SQL, saya tidak dapat memuat rakitan khusus ke server ini sehingga tidak dapat menggunakan ekspresi reguler.
Kolom sebenarnya adalah varchar (200) . Kolasi adalah Latin1_General_CI_AS. Saya menggunakan SQL Server 2012 Edisi Standar.
Jawaban:
Kesulitan terbesar dalam mencapai solusi yang tepat adalah dalam menentukan dengan tepat karakter apa yang akan dimasukkan (atau dikecualikan, arah mana pun yang lebih masuk akal untuk operasi). Berarti:
VARCHAR
data / ASCII atauNVARCHAR
/ data Unicode? Daftar karakter tanda baca untuk data ASCII tergantung pada Halaman Kode yang pada gilirannya tergantung pada Collation. ( dalam Pertanyaan ini kita berurusan dengan data ASCII ).Latin1_General_CI_AS
).
,,
,;
,:
, dll) atau apakah itu karakter non-alfanumerik berarti?¢
,£
,¥
, dll?©
dan™
?Â
,É
,Ñ
,ß
,Þ
disertakan?Æ
/æ
karakter?Untuk membantu memfasilitasi kejelasan mengenai perilaku yang diharapkan, permintaan berikut akan menampilkan semua 256 karakter dari set karakter Latin1 (yaitu Kode Page 1252) dan bagaimana dua variasi dari solusi yang diusulkan @ Shaneis beroperasi. Kolom pertama (diberi label sebagai
Latin1_General_CI_AS
) menunjukkanLIKE
klausa seperti yang diusulkan oleh @Shaneis (pada tulisan ini) dan kolom kedua (diberi label sebagaiLatin1_General_100_BIN2
) menunjukkan modifikasi di mana saya mengesampingkan Collation untuk menentukan yang biner (yaitu Collation yang diakhiri dengan_BIN2
;_BIN
Kolasi sudah tidak digunakan lagi jadi jangan menggunakannya jika Anda memiliki akses ke_BIN2
versi) yang berarti saya juga perlu menambahkanA-Z
rentang untuk menyaring huruf besar karena Kolasi saat ini tidak peka terhadap huruf besar-kecil:MEMPERBARUI
Harus disebutkan bahwa JIKA seseorang benar-benar mencari untuk menemukan karakter yang diklasifikasikan sebagai "tanda baca" (dan bukan "simbol mata uang", "simbol matematika", dll), dan JIKA seseorang tidak dilarang menggunakan SQLCLR / memuat kebiasaan Assembly (SQLCLR diperkenalkan dengan SQL Server 2005, dan saya belum menemukan alasan yang bagus untuk tidak mengizinkannya, terutama karena Azure SQL Database V12 mendukung
SAFE
Assemblies), maka Anda dapat menggunakan Ekspresi Reguler, tetapi bukan karena kebanyakan orang akan menebak.Daripada menggunakan Ekspresi Reguler untuk membangun rentang karakter yang lebih fungsional, atau bahkan daripada menggunakan sesuatu seperti
\w
(artinya karakter "kata"), Anda dapat menentukan Kategori Unicode dari karakter yang ingin Anda filter, dan ada beberapa kategori yang ditentukan :https://www.regular-expressions.info/unicode.html#category
Anda bahkan dapat menentukan Blok Unicode untuk difilter, seperti "InBengali" atau "InDingbats" atau "InOptical_Character_Recognition", dll:
https://www.regular-expressions.info/unicode.html#block
Ada banyak contoh membuat fungsi RegEx untuk SQL Server (meskipun kebanyakan contoh tidak mengikuti praktik terbaik SQLCLR), atau Anda dapat mengunduh versi gratis dari pustaka SQL # (yang saya buat), dan menggunakan fungsi skalar RegEx_IsMatch sebagai berikut :
The
\p{P}
ekspresi berarti\p
= Unicode Kategori, dan{P}
= semua tanda baca (sebagai lawan jenis tertentu tanda baca, seperti "Connector Tanda baca"). DAN, kategori "Tanda Baca" mencakup semua tanda baca di semua bahasa! Anda dapat melihat daftar lengkap di situs Unicode.org melalui tautan berikut (saat ini ada 717 Poin Kode dalam kategori itu):http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AGeneral_Category%3DPunctuation%3A%5D
Versi terbaru dari kueri pengujian yang ditunjukkan di atas, termasuk bidang lain yang menggunakan SQL # .RegEx_IsMatch dengan
\p{P}
, dan hasil dari semua 3 tes di semua 256 karakter Kode Page 1252 (yaitu Latin1_General) telah diposting di PasteBin.com di:T-SQL query dan hasil untuk memfilter jenis karakter
PEMBARUAN
Berikut ini disebutkan dalam diskusi terkait:
Pada kasus ini:
Ada 11 karakter non-Inggris yang termasuk dalam set karakter Latin1 / Halaman Kode yang tidak cocok dengan
a-z
rentang. Mereka adalah:ð Ð Þ þ œ Œ š Š ž Ž Ÿ
. Ini perlu ditambahkan ke wildcard, dan sementara tidak perlu saat ini, tidak ada salahnya untuk menambahkanA-Z
sehingga pola bekerja dengan baik pada susunan case-sensitive. Hasil akhirnya adalah:LIKE '%[^a-zA-Z0-9ðÐÞþœŒšŠžŽŸ]%'
Mempertimbangkan bahwa data ini dapat memasukkan "nama hotel dari seluruh dunia", saya sangat merekomendasikan untuk mengubah tipe data kolom
NVARCHAR
sehingga Anda dapat menyimpan semua karakter dari semua bahasa. Menjaga ini sebagaiVARCHAR
menjalankan risiko yang sangat tinggi pada akhirnya kehilangan data karena Anda hanya dapat mewakili bahasa berbasis Latin, dan bahkan tidak sepenuhnya untuk mereka yang diberi enam kategori Unicode tambahan yang menyediakan karakter terkait Latin tambahan.sumber
Saya mungkin terlalu menyederhanakan ini sedikit tetapi, jika kita mengatakan bahwa tanda baca adalah yang tersisa ketika nilai alfanumerik dihapus, maka berikut ini akan mencari string yang memiliki karakter non-alfanumerik di dalamnya.
sumber