Usuń wszystkie znaki specjalne za pomocą RegExp

234

Chciałbym RegExp, który usunie wszystkie znaki specjalne z ciągu. Próbuję czegoś takiego, ale to nie działa w IE7, chociaż działa w przeglądarce Firefox.

var specialChars = "!@#$^&%*()+=-[]\/{}|:<>?,.";

for (var i = 0; i < specialChars.length; i++) {
  stringToReplace = stringToReplace.replace(new RegExp("\\" + specialChars[i], "gi"), "");
}

Pomocny byłby również szczegółowy opis RegExp.

Timothy Ruhle
źródło
18
Coś takiego byłoby lepiej jako biała lista, a nie czarna lista. wtedy możesz po prostu zrobić [az] | [0-9] | \ s
Ape-inago
Jakiś błąd skryptu? Czy debugowałeś? Albo umieść blok try ... catch w kodzie javascript.
Kangkan,
@ Ape-inago, czy możesz wyjaśnić RegExp nieco więcej, proszę
Timothy Ruhle
3
Proszę zdefiniować „znak specjalny”! Czy „風” jest dla Ciebie specjalne? (Myśląc o tym, zobaczysz punkt @ Ape-iango.)
deceze
7
Nie sądzę, żeby ktokolwiek tutaj miał na myśli jakieś przestępstwo. Byłem wcześniej spalony, robiąc to jako czarną listę, ponieważ zawsze są te małe „gotcha”, które ostatecznie przechodzą (jak przykłady deceze). Ostatecznie prawidłowe podejście bardziej dotyczy tego, dlaczego próbujesz to zrobić.
Ape-inago,

Odpowiedzi:

612
var desired = stringToReplace.replace(/[^\w\s]/gi, '')

Jak wspomniano w komentarzach, łatwiej jest to zrobić jako białą listę - zamień znaki, których nie ma na liście bezpiecznych.

Znak caret ( ^) jest negacją zestawu [...], gipowiedzmy globalną i bez rozróżniania wielkości liter (ten drugi jest nieco redundantny, ale chciałem o tym wspomnieć), a lista bezpiecznych elementów w tym przykładzie to cyfry, znaki słowne, podkreślenia ( \w) i białe znaki ( \s).

annakata
źródło
50
To rozwiązanie nie działa w przypadku symboli innych niż angielski. Na przykład „Їжак”.
Mewa
4
Możesz także użyć wielkiej \ W zamiast ^ \ w. \ W: Dopasowuje dowolny znak inny niż słowo. Odpowiednik [^ A-Za-z0-9_]. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
delkant
@ Mewa Dodałem odpowiedź, która obsługuje Unicodes.
freedev
1
aby zaakceptować słowa akcentowane, jak w języku portugalskim, wykonaj następujące czynności: stringToReplace.replace (/ [^ A-zÀ-ú \ s] / gi, '')
alansiqueira27 10.04.17
1
Aby dodać większość języków europejskich (norweski, szwedzki, niemiecki, portoguise, hiszpański) stringToReplace.replace (/ [^ \ w \ s \ xc0-xff] / gi, ''). Aby uwzględnić inne języki, można użyć zakresów Unicode. Zobacz: stackoverflow.com/questions/150033/…
Eskil Mjelva Saatvedt
105

Pamiętaj, że jeśli nadal chcesz wykluczyć zestaw, w tym ukośniki i znaki specjalne, możesz wykonać następujące czynności:

var outString = sourceString.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');

zwróć szczególną uwagę, że aby uwzględnić także znak „minus”, musisz uciec przed odwrotnym ukośnikiem, jak ta ostatnia grupa. jeśli tego nie zrobisz, wybierze również 0-9, co prawdopodobnie jest niepożądane.

brak wejścia
źródło
10
doskonałe rozwiązanie! zaakceptowana odpowiedź działa tylko w języku angielskim, to działa na wszystkich językach (o ile sprawdziłem). dzięki :)
Ronen Ness,
1
@knutole usuń ?część zestawu znaków do przodu. wyświetla listę znaków, które chcesz usunąć, więc wykluczenie go z usuwania spowoduje z natury włączenie go do wyniku końcowego.
noinput
Działa to świetnie, pasuje idealnie do każdego języka, wystarczy dodać znak, który chcesz zastąpić i to wszystko. Dzięki.
Elros Romeo
21

Zwykłe wyrażenie regularne JavaScript nie obsługuje liter Unicode .

Nie używaj [^\w\s], spowoduje to usunięcie liter z akcentami (jak àèéìòù), nie wspominając o cyrylicy lub chińskim, litery pochodzące z takich języków zostaną całkowicie usunięte.

Naprawdę nie chcesz usuwać tych liter razem ze wszystkimi znakami specjalnymi. Masz dwie szanse:

  • Dodaj w regex wszystkie znaki specjalne, których nie chcesz usuwać,
    na przykład: [^èéòàùì\w\s].
  • Zajrzyj na xregexp.com . XRegExp dodaje podstawową obsługę dopasowania Unicode poprzez \p{...}składnię.

var str = "Їжак::: résd,$%& adùf"
var search = XRegExp('([^?<first>\\pL ]+)');
var res = XRegExp.replace(str, search, '',"all");

console.log(res); // returns "Їжак::: resd,adf"
console.log(str.replace(/[^\w\s]/gi, '') ); // returns " rsd adf"
console.log(str.replace(/[^\wèéòàùì\s]/gi, '') ); // returns " résd adùf"
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.js"></script>

freedev
źródło
3
Dobrze wiedzieć o internacjonalizacji, nie miałem pojęcia, że ​​wyrażenia regularne JS nie są nastawione na UTF-8.
LessQuesar,
Nie możesz wstawić wszystkich poprawnych liter UTF-8 do var str
Seagull
@ Mewa tak, ale jeśli nie piszesz aplikacji zgodnej na całym świecie, możesz pragmatycznie umieścić tylko listę prawidłowych liter UTF-8 dla bieżącej lokalizacji. W moim przypadku dla języka włoskiego jest tylko kilka liter.
freedev
7

Pierwsze rozwiązanie nie działa dla żadnego alfabetu UTF-8. (Wytnie tekst taki jak Їжак). Udało mi się stworzyć funkcję, która nie korzysta z RegExp i korzysta z dobrej obsługi UTF-8 w silniku JavaScript. Pomysł jest prosty, jeśli symbol jest taki sam wielkimi literami, a małe litery to znak specjalny. Jedyny wyjątek dotyczy białych znaków.

function removeSpecials(str) {
    var lower = str.toLowerCase();
    var upper = str.toUpperCase();

    var res = "";
    for(var i=0; i<lower.length; ++i) {
        if(lower[i] != upper[i] || lower[i].trim() === '')
            res += str[i];
    }
    return res;
}

Aktualizacja: należy pamiętać, że to rozwiązanie działa tylko w przypadku języków, w których występują małe i duże litery. W językach takich jak chiński to nie zadziała.

Aktualizacja 2: Doszedłem do oryginalnego rozwiązania, kiedy pracowałem nad rozmytym wyszukiwaniem. Jeśli próbujesz również usunąć znaki specjalne w celu zaimplementowania funkcji wyszukiwania, istnieje lepsze podejście. Użyj dowolnej biblioteki transliteracji, która wygeneruje ciąg tylko ze znaków łacińskich, a następnie prosty Regexp wykona całą magię usuwania znaków specjalnych. (Będzie to działać również w przypadku języka chińskiego, a Ty również otrzymasz świadczenia dodatkowe, wykonując Tromsø== Tromso).

Mewa
źródło
Doskonale, jak ta odpowiedź! Używam go do tworzenia prawidłowej nazwy pliku i mam rozszerzone twoje rozwiązanie do usuwania spacji (kompatybilnych z Linux / Unix) i dopuszczania liczb. Rozszerzyłem więc instrukcję if (dotyczy jQuery): if (str [i]! == '' && (lower [i]! = Upper [i] || lower [i] .trim () === '' | | $ .isNumeric (str [i])))
Jonny
w wielu językach nie ma wielkich liter ... dlatego funkcja uzna poprawne wprowadzanie za znaki specjalne
Yair Levy
Chińskie znaki są jednym przykładem, który zostaje przez to
rozebrany
Kiedy tworzyłem to rozwiązanie, niestety nie myślałem o językach takich jak chiński. Należy zaproponować rozwiązanie, ponieważ poprzednie odpowiedzi również nie będą działać.
Mewa
1

Używam RegexBuddy do debugowania moich wyrażeń regularnych, ponieważ ma prawie wszystkie języki bardzo przydatne. Niż skopiuj / wklej dla docelowego języka. Wspaniałe narzędzie i niezbyt drogie.

Więc skopiowałem / wkleiłem twoje wyrażenie regularne, a twoim problemem jest to, że [,] są znakami specjalnymi w wyrażeniu regularnym, więc musisz uciec przed nimi. Wyrażenie regularne powinno więc brzmieć:

millebii
źródło
0

dlaczego nie robisz czegoś takiego:

re = /^[a-z0-9 ]$/i;
var isValid = re.test(yourInput);

aby sprawdzić, czy dane wejściowe zawierają jakieś specjalne znaki

I
źródło
17
OP twierdzi, że próbuje usunąć znaki specjalne, nie sprawdzając, czy istnieją.
annakata
Jest to jedno z dobrych rozwiązań, ale pozwoli tylko na litery alfabetu angielskiego i spację, ale usunie znaki takie jak, èéòàùìa w niektórych przypadkach nie będzie to rozwiązanie
mapmalith
0

str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "")Zrobiłem coś takiego. Ale są ludzie, którzy zrobili to znacznie łatwiejstr.replace(/\W_/g,"");

Eldar Mammadov
źródło
Większość rzeczy w twoim podejściu jest zbędna, ponieważ \Wzawiera niektóre postacie. Ale dlaczego odfiltrowujesz liczby? To nie są znaki specjalne.
user4642212,