Wyrażenie regularne pozwalające na odstępy między wyrazami

191

Chcę wyrażenia regularnego, które zapobiega symbolom i dopuszcza tylko litery i cyfry. Poniższe wyrażenie regularne działa świetnie, ale nie pozwala na spacje między słowami.

^[a-zA-Z0-9_]*$

Na przykład przy użyciu tego wyrażenia regularnego „HelloWorld” jest w porządku, ale „Hello World” nie pasuje.

Jak mogę go dostosować, aby spacje były dozwolone?

lawphotog
źródło

Odpowiedzi:

372

tl; dr

Po prostu dodaj spację w swojej klasie postaci .

^[a-zA-Z0-9_ ]*$

 


Teraz, jeśli chcesz być surowy ...

Powyższe nie jest dokładnie poprawne. Z uwagi na fakt, że *oznacza zero lub więcej , pasowałoby do wszystkich następujących przypadków, których zwykle nie oznacza dopasowanie:

  • Pusty ciąg „”.
  • Ciąg złożony w całości ze spacji „”.
  • Ciąg, który prowadzi i / lub prowadzi ze spacjami „Hello World”.
  • Ciąg zawierający wiele spacji między słowami „Hello World”.

Początkowo nie sądziłem, że takie szczegóły są warte wniknięcia, ponieważ OP zadawał tak podstawowe pytanie, że wydawało się, że surowość nie jest problemem. Teraz, gdy pytanie zyskało popularność, chcę powiedzieć…

... użyj odpowiedzi @ stema .

Co moim zdaniem (bez użycia \w) przekłada się na:

^[a-zA-Z0-9_]+( [a-zA-Z0-9_]+)*$

(Niezależnie od tego, proszę głosować na @stema).

Kilka rzeczy, na które należy zwrócić uwagę w związku z tą (i @ macierzystą) odpowiedzią:

  • Jeśli chcesz zezwolić na wiele spacji między wyrazami (powiedzmy, jeśli chcesz dopuścić przypadkowe podwójne spacje lub jeśli pracujesz z wklejonym tekstem z pliku PDF), dodaj +po spacji:

    ^\w+( +\w+)*$
  • Jeśli chcesz zezwolić na tabulatory i znaki nowej linii (białe znaki), zamień spację na \s+:

    ^\w+(\s+\w+)*$

    Tutaj sugeruję +domyślnie, ponieważ, na przykład, łamanie linii systemu Windows składa się z dwóch białych znaków w sekwencji \r\n, więc musisz +złapać oba.

Wciąż nie działa?

Sprawdź, jakiego dialektu wyrażeń regularnych używasz. * W językach takich jak Java musisz uciec swoje backslashy, IE \\w i \\s. W starszych lub więcej podstawowych języków i narzędzi, jak sed, \wi \snie są zdefiniowane, więc pisać je z klas postaci, np [a-zA-Z0-9_] i [\f\n\p\r\t], odpowiednio.

 


* Wiem, że to pytanie jest oznaczone, ale w oparciu o ponad 25 000 wyświetleń, zgaduję, że to nie tylko ludzie napotykają to pytanie. Obecnie jest to pierwsze trafienie w Google dla wyszukiwanego wyrażenia, słowa w przestrzeni wyrażeń regularnych .

Andrew Cheong
źródło
3
pozwala na pusty ciąg
Neha Choudhary
1
Wow, takie proste! dzięki. Czy nie ma witryny ani czegoś, co można by wykorzystać do generowania wyrażeń regularnych, dla noobów mam na myśli ...
Pierre
1
@Pierre - Trudno jest przyjmować ludzkie instrukcje i konwertować je na wyraźne reguły. (Ludzki język jest płynny i pełen dwuznaczności, a nasze mózgi wykonują większość pracy wymaganej do rozwiązania problemów i uzupełnienia braków. Komputery nie mają takiego mózgu, a sprytne próby naśladowania go nie są jeszcze wystarczająco potężne. ) Istnieją narzędzia, takie jak debuggex.com, które reprezentują wyrażenia regularne wizualnie, ale tak atrakcyjne, jak to jest, może nie być bardzo pomocne dla początkujących. Polecam jednak interaktywny samouczek, aby opanować podstawy.
Andrew Cheong,
1
Tak, również wyrażenie regularne będzie pasować, jeśli będą tylko spacje. Moja odpowiedź była na komentarz Neha Choudary.
Rajshekar Reddy
1
@Pierre Trzy lata później - natknąłem się dziś na to pytanie, zobaczyłem twój komentarz; Używam regex hero ( regexhero.net ) do testowania wyrażeń regularnych. Myślę, że wersja online działa tylko w Internet Explorerze z Silverlight, ale jest lepsza niż nic.
Michael Armes
121

Jedną z możliwości byłoby po prostu dodanie spacji do twojej klasy postaci, jak sugerował acheong87, zależy to od tego, jak surowo jesteś na swoim wzorcu, ponieważ pozwoliłoby to również na ciąg rozpoczynający się od 5 spacji lub ciągi składające się tylko ze spacji.

Inną możliwością jest zdefiniowanie wzoru:

Użyję \wtego jest w większości smaków regexowych takich samych jak [a-zA-Z0-9_](w niektórych jest oparty na Unicode)

^\w+( \w+)*$

Umożliwi to serię co najmniej jednego słowa, a słowa zostaną podzielone spacjami.

^ Dopasuj początek łańcucha

\w+ Dopasuj serię co najmniej jednego znaku słowa

( \w+)*to grupa powtarzana 0 lub więcej razy. W grupie oczekuje spacji, po której następuje seria co najmniej jednego znaku słowa

$ dopasowuje koniec łańcucha

stema
źródło
To: regex101.com/#javascript stanowi również dobre wyjaśnienie wzorca wyrażenia regularnego, który chcesz przeanalizować.
Dark Star1
Niezły regex, dużo prostszy niż wiele [0-9a-z] itd.
George
26

Ten działał dla mnie

([\w ]+)
Mario Rugeles Perez
źródło
1
Ta odpowiedź nie ma wyjaśnienia.
mickmackusa,
12

Spróbuj z:

^(\w+ ?)*$

Wyjaśnienie:

\w             - alias for [a-zA-Z_0-9]
"whitespace"?  - allow whitespace after word, set is as optional
hsz
źródło
2
To wywoła piekło.
nhahtdh
1
Na przykład, biorąc pod uwagę niepasujący ciąg ggggggggggggggggggggggggggggggggggggg;, regex zajmie bardzo dużo czasu, aby osiągnąć wynik z powodu nadmiernego cofania.
nhahtdh,
Ok, więc co sugerujesz?
hsz
7

Zakładam, że nie chcesz początkowej / końcowej przestrzeni. Oznacza to, że musisz podzielić wyrażenie regularne na „pierwszą postać”, „rzeczy na środku” i „ostatnią postać”:

^[a-zA-Z0-9_][a-zA-Z0-9_ ]*[a-zA-Z0-9_]$

lub jeśli używasz składni podobnej do perla:

^\w[\w ]*\w$

Ponadto: jeśli celowo sformułowałeś wyrażenie regularne, że pozwala on również na puste ciągi, musisz uczynić całą rzecz opcjonalną:

^(\w[\w ]*\w)?$

Jeśli chcesz zezwolić tylko na pojedyncze znaki spacji, wygląda to nieco inaczej:

^((\w+ )*\w+)?$

To dopasowuje 0.. słów, po których następuje pojedyncza spacja, plus jedno słowo bez spacji. I sprawia, że ​​całość jest opcjonalna, aby umożliwić puste ciągi.

creinig
źródło
Przestrzeń i \snie są równoważne. \spasuje więcej niż tylko przestrzeń.
nhahtdh
@nhahtdh: Dzięki za komentarz. Myślę, że jestem zbyt przyzwyczajony do dopasowywania białych znaków. Odpowiedź jest naprawiona.
Creinig 18.03.13
Czy to możliwe, że brakuje pierwszego nawiasu zamykającego)? Nie jestem pewien, czy tego nie próbowałem.
ssinfod
@ssinfod: Good catch. W rzeczywistości nawias otwierający jest w tym przykładzie zbędny. Dzięki.
Creinig
4

To wyrażenie regularne

^\w+(\s\w+)*$

pozwoli tylko jedną spację między słowami i nie będzie spacji wiodących ani końcowych.

Poniżej znajduje się wyjaśnienie wyrażenia regularnego:

  1. ^ Potwierdź pozycję na początku łańcucha
  2. \w+ Dopasuj dowolny znak słowa [a-zA-Z0-9_]
    1. Kwantyfikator: +od jednego do nieograniczonego czasu, tyle razy, ile to możliwe, zwracając w razie potrzeby [chciwy]
  3. 1. grupa przechwytująca (\s\w+)*
    1. Kwantyfikator: *od zera do nieograniczonej liczby razy, tyle razy, ile to możliwe, zwracając w razie potrzeby [chciwy]
    2. \s Dopasuj dowolny biały znak [\r\n\t\f ]
    3. \w+ Dopasuj dowolny znak słowa [a-zA-Z0-9_]
      1. Kwantyfikator: +od jednego do nieograniczonego czasu, tyle razy, ile to możliwe, zwracając w razie potrzeby [chciwy]
  4. $ Potwierdź pozycję na końcu łańcucha
Amadeus Sánchez
źródło
2

To nie pozwala na miejsce na początku. Ale pozwala na spacje między słowami. Pozwala również na znaki specjalne między słowami. Dobry regex dla pól FirstName i LastName.

\w+.*$
jaxxbo
źródło
Ta odpowiedź jest niepoprawna / niedokładna. Ten wzór pasuje do co najmniej jednego znaku alfanumerycznego, podkreślenia, a następnie zero lub więcej dowolnych znaków innych niż nowa linia. Nie jest dobre dla PO.
mickmackusa,
2

Tylko dla alfabetów:

^([a-zA-Z])+(\s)+[a-zA-Z]+$

W przypadku wartości alfanumerycznych i _:

^(\w)+(\s)+\w+$
bibliofilsagar
źródło
1
nie jest to dobry przykład, ponieważ (coś) + to nie to samo co (coś +). W pierwszym przykładzie tylko jeden znak zostanie przechwycony jako 1 USD.
Znik
0

Spróbuj tego: (wersja Python)

"(A-Za-z0-9 ){2, 25}"

zmień górny limit na podstawie zestawu danych

MoMo
źródło
0

Po prostu dodaj spację do końca wzoru regularnego w następujący sposób:

[a-zA-Z0-9_ ]
KayV
źródło
-1

Przyjrzał się wielu z tych rzekomych odpowiedzi ...

... i bupki po przeszukaniu Przepełnienia stosu, a także innych witryn dla wyrażenia regularnego, które pasuje do dowolnego ciągu bez początkowych lub końcowych białych znaków i tylko jedną spację między wyrazami ściśle alfanumerycznymi.

^[a-zA-Z]+[(?<=\d\s]([a-zA-Z]+\s)*[a-zA-Z]+$

W ten sposób łatwo można go zmienić na alfanumeryczny:

^[a-zA-Z0-9]+[(?<=\d\s]([a-zA-Z0-9]+\s)*[a-zA-Z0-9]+$

(To nie pasuje do pojedynczych słów, ale po prostu użyj przełącznika / if-else z prostym, ^[a-zA-Z0-9]+$jeśli chcesz dodatkowo złapać pojedyncze słowa.)

ciesz się: D

LokizFenrir
źródło
3
[(?<=\d\s]dopasowuje jeden znak: (, ?, <, =, cyfra lub znak spacji, i że nie może być to, co masz na myśli. Jeśli miałby to być wygląd, powinien (?<=\d\s), ale nie ma sensu; regex nigdy by się nie zgadzał.
Alan Moore
Do głosujących: Proszę nie głosować za złymi rozwiązaniami. Mylą innych użytkowników i przekonują ich, że regex może robić rzeczy, których nie robi.
Wiktor Stribiżew
-1

Uważam, że ten działa dobrze dla „FullName”:

([a-z',.-]+( [a-z',.-]+)*){1,70}/
Adam K. Dean
źródło
-4

próbować .*? aby pozwolić na białe przestrzenie, zadziałało to dla mnie

użytkownik4035152
źródło
To dlatego, że .pasuje do wszystkiego. Jest bardzo prawdopodobne, że nie będzie to rozwiązanie tutaj.
rubik
dopasowuje zero lub dowolne znaki, w zależności od tego, co jest przed i po tej sekwencji. to będzie pasowało jak najmniej. pojedyncza kropka oznacza dowolny pojedynczy znak.
Znik