Jak możesz usunąć wszystkie znaki, które nie są alfabetyczne z ciągu?
A co z niealfanumerycznymi?
Czy musi to być funkcja niestandardowa, czy też istnieją rozwiązania bardziej dające się uogólnić?
Jak możesz usunąć wszystkie znaki, które nie są alfabetyczne z ciągu?
A co z niealfanumerycznymi?
Czy musi to być funkcja niestandardowa, czy też istnieją rozwiązania bardziej dające się uogólnić?
Wypróbuj tę funkcję:
Create Function [dbo].[RemoveNonAlphaCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare @KeepValues as varchar(50)
Set @KeepValues = '%[^a-z]%'
While PatIndex(@KeepValues, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
Return @Temp
End
Nazwij to tak:
Select dbo.RemoveNonAlphaCharacters('abc1234def5678ghi90jkl')
Gdy zrozumiesz kod, zobaczysz, że stosunkowo łatwo jest go zmienić, aby usunąć również inne znaki. Możesz nawet uczynić to wystarczająco dynamicznym, aby pasował do Twojego wzorca wyszukiwania.
Mam nadzieję, że to pomoże.
Parametryzowane wersja G Mastros ' niesamowitej odpowiedzi :
Tylko alfabetycznie:
Tylko numeryczne:
Tylko alfanumeryczne:
Niealfanumeryczne:
źródło
SELECT dbo.fn_StripCharacters('a1!s2 spaces @d3# f4$', '^a-z0-9\s')
nadal usuwających białe znaki. Próbowałem też użyć,[[:blank:]]
ale to psuje funkcję i nic nie jest usuwane z ciągu. Najbliższe otrzymane Ive to użycie:SELECT dbo.fn_StripCharacters('a1!s2 spaces @d3# f4$', '^a-z0-9 ')
(zakodowanie spacji we wzorcu wyrażenia regularnego). Jednak to nie usuwa podziałów wierszy.SELECT dbo.fn_StripCharacters('a1!s2 spaces @d3# f4$', '^ a-z0-9')
Wierz lub nie, ale w moim systemie ta brzydka funkcja sprawdza się lepiej niż elegancka G Mastros.
źródło
ASCII
tutaj liczby całkowitej i porównaj bezpośrednio wynikSUBSTRING
z niektórymiSET @ch=SUBSTRING(@s, @p, 1)
IF @ch BETWEEN '0' AND '9' OR @ch BETWEEN 'a' AND 'z' OR @ch BETWEEN 'A' AND 'Z' ...
Wiedziałem, że SQL źle radzi sobie z manipulacją ciągami, ale nie sądziłem, że będzie to takie trudne. Oto prosta funkcja do usunięcia wszystkich liczb z ciągu. Byłoby na to lepsze sposoby, ale to jest początek.
Wynik
Runda 2 - Czarna lista oparta na danych
Wynik
Moje wyzwanie dla czytelników: czy możesz uczynić to bardziej wydajnym? A co z rekurencją?
źródło
Jeśli jesteś podobny do mnie i nie masz dostępu do dodawania funkcji do swoich danych produkcyjnych, ale nadal chcesz wykonać tego rodzaju filtrowanie, oto czyste rozwiązanie SQL wykorzystujące tabelę PIVOT do ponownego złożenia przefiltrowanych elementów.
Uwaga : zakodowałem na stałe tabelę do 40 znaków, będziesz musiał dodać więcej, jeśli masz dłuższe ciągi do filtrowania.
źródło
Po przyjrzeniu się wszystkim przedstawionym rozwiązaniom pomyślałem, że musi istnieć czysta metoda SQL, która nie wymaga funkcji ani zapytania CTE / XML i nie wymaga trudnego utrzymania zagnieżdżonych instrukcji REPLACE. Oto moje rozwiązanie:
Zaletą zrobienia tego w ten sposób jest to, że prawidłowe znaki są zawarte w jednym ciągu w zapytaniu podrzędnym, co ułatwia rekonfigurację dla innego zestawu znaków.
Wadą jest to, że musisz dodać wiersz SQL dla każdego znaku, aż do rozmiaru kolumny. Aby ułatwić to zadanie, użyłem tylko poniższego skryptu Powershell, w tym przykładzie dla VARCHAR (64):
źródło
Oto inny sposób usuwania znaków niealfabetycznych za pomocą rozszerzenia
iTVF
. Po pierwsze, potrzebujesz rozdzielacza ciągów opartego na wzorze. Oto jeden zaczerpnięty z artykułu Dwaina Campa :Teraz, gdy masz rozdzielacz oparty na wzorcu, musisz podzielić ciągi pasujące do wzorca:
a następnie połącz je z powrotem, aby uzyskać pożądany wynik:
PRÓBA
Wynik:
źródło
To rozwiązanie, zainspirowane rozwiązaniem pana Allena, wymaga
Numbers
tabeli liczb całkowitych (którą powinieneś mieć pod ręką, jeśli chcesz wykonywać poważne operacje zapytań z dobrą wydajnością). Nie wymaga CTE. Możesz zmienićNOT IN (...)
wyrażenie, aby wykluczyć określone znaki, lub zmienić je na wyrażenieIN (...)
OR,LIKE
aby zachować tylko określone znaki.źródło
Oto rozwiązanie, które nie wymaga tworzenia funkcji ani wyświetlania wszystkich wystąpień znaków do zastąpienia. Używa rekurencyjnej instrukcji WITH w połączeniu z PATINDEX, aby znaleźć niechciane znaki. Zastąpi wszystkie niechciane znaki w kolumnie - do 100 unikalnych złych znaków zawartych w dowolnym podanym ciągu. (Np. „ABC123DEF234” zawierałoby 4 złe znaki 1, 2, 3 i 4) Limit 100 to maksymalna liczba rekursji dozwolona w instrukcji WITH, ale nie narzuca to ograniczenia liczby wierszy do przetworzenia, co jest ograniczona tylko dostępną pamięcią.
Jeśli nie chcesz DISTINCT wyników, możesz usunąć dwie opcje z kodu.
źródło
Umieściłem to w obu miejscach, w których nazywa się PatIndex.
dla funkcji niestandardowej powyżej RemoveNonAlphaCharacters i zmieniono jej nazwę RemoveNonAlphaNumericCharacters
źródło
- Najpierw utwórz jedną funkcję
Teraz wywołaj tę funkcję jak
Jego wynik jak
źródło
Z punktu widzenia wydajności użyłbym funkcji Inline:
źródło
Oto kolejne rekurencyjne rozwiązanie CTE, oparte na odpowiedzi @Gerhard Weiss tutaj . Powinieneś móc skopiować i wkleić cały blok kodu do SSMS i tam bawić się nim. Wyniki zawierają kilka dodatkowych kolumn, które pomagają nam zrozumieć, co się dzieje. Zajęło mi trochę czasu, zanim zrozumiałem wszystko, co dzieje się zarówno z PATINDEX (RegEx), jak i rekurencyjnym CTE.
źródło
Używając tabeli liczb wygenerowanych przez CTE do zbadania każdego znaku, a następnie FOR XML, aby połączyć z ciągiem zachowanych wartości, możesz ...
źródło
źródło
ten sposób nie zadziałał dla mnie, ponieważ starałem się zachować arabskie litery, próbowałem zastąpić wyrażenie regularne, ale też nie zadziałało. napisałem inną metodę pracy na poziomie ASCII, ponieważ była to moja jedyna opcja i zadziałała.
UDAĆ SIĘ
źródło
Chociaż post jest trochę stary, chciałbym powiedzieć, co następuje. Problem, który miałem z powyższym rozwiązaniem polega na tym, że nie odfiltrowuje ono znaków takich jak ç, ë, ï itp. Zaadaptowałem funkcję w następujący sposób (użyłem tylko ciągu 80 varchar do oszczędzania pamięci):
źródło
Właśnie znalazłem to wbudowane w Oracle 10g, jeśli tego właśnie używasz. Musiałem usunąć wszystkie znaki specjalne, aby porównać numery telefonów.
źródło