2013-02-13 13 views
6

W Regeksie stawałem się coraz lepszy, ale wymyśliłem coś, co wykracza poza to, co obecnie mogę zrobić.Dopasuj pojedyncze słowo z możliwą interpunkcją lub liczbą mnogą na końcu (Regex)

Chcę zbudować funkcję do przetestowania (return true lub false), aby sprawdzić, czy słowo znajduje się w ciągu znaków. Ale nie chciałbym mieć pozytywnego wyniku, jeśli słowo zostało znalezione w innym słowie. Chciałbym również skorzystać z możliwości sprawdzenia pluralizacji.

Oto kilka przykładów wyników spodziewam się dostać:

Słowo szukać: „bar”

„Struny do przeszukania” // co powinno powrócić jako

"foo bar" // true

"foo bar". // true

"foo bar!" // true (byłaby prawdziwa z każdą inną interpunkcją przed lub po "bar")

"paski foo". // true

"foo bares". // true (nawet jeśli bares ma inne znaczenie niż pręty, byłbym w porządku z tym powracającym prawdziwym, ponieważ musiałbym sprawdzić słowa, które pluralizują się za pomocą "es" i nie oczekiwałbym zbudowania wyrażeń regularnych, aby wiedzieć, które słowa pluralize z "s", a które "es")

"nazywam się Bart Simpson" // false (bar jest faktycznie częścią "bart")

"Bart Simpson poszedł do baru." // true

będę przy użyciu JavaScript/jQuery, aby sprawdzić meczów

Dziękuję bardzo za pomoc!

+0

Tak więc "dziecko" nie jest zgodne z "dziećmi", prawda? –

+0

Tak, nie oczekiwałbym, że "dziecko" będzie pasowało do "dzieci". – rgbflawed

+4

Pluralizacja nie jest łatwa do zrobienia przy użyciu wyrażeń regularnych. Co z _mouse/mice_ i _colossus/colossi_? – Halcyon

Odpowiedz

4
var rgx = new RegExp('\\b' + word + '(?:es|s)?\\b'); 
rgx.test(string); 

ten powróci true dla wszystkich ciągów ty określonych w zapytaniu. \b reprezentuje "granicę słowa", która moim zdaniem jest dowolną postacią w \W (łącznie z kropką i wykrzyknikiem) oraz początkiem lub końcem łańcucha.

+0

To działa świetnie! Po prostu musiałem dokonać jednej zmiany, aby to zadziałało. Zmieniono "Regex" na "RegExp". Dziękuję bardzo EP! – rgbflawed

+0

@StevenJenkins oops, używałem 'RegExp' we wszystkich moich testach, ale najpierw napisałem' Regex' w odpowiedzi. –

0
/ (bar((e)?s)?)[ !?.]/ 

w zależności od tego, czego potrzebujesz, to może działać. nie znajdzie dwóch pasków w ciągu "prętów" ze względu na nakładające się spacje.

/ (bar((e)?s)?)(?=[ !?.])/ 

który powinien działać z „Bary” (dwa mecze) Ponieważ js1.5 który jest obsługiwany przez wszystkie przeglądarki i tak w dzisiejszych czasach.

2

Zostało to już odebrane i zaakceptowane, ale pomyślałem, że podam nieznacznie podejście, które lepiej pasuje do liczby mnogiej.Poza tym, że używa dokładnie taką samą logikę jako roztwór @ExplosionPills':

(function() { 
    var isWord = function(word) { return /^[a-z]+$/i.test(word); }, 

     exceptions = { 
     man: 'men', 
     woman: 'women', 
     child: 'children', 
     mouse: 'mice', 
     tooth: 'teeth', 
     goose: 'geese', 
     foot: 'feet', 
     ox: 'oxen' 
     }, 

     pluralise = function(word) { 
     word = word.toLowerCase(); 

     if (word in exceptions) { 
      // Exceptions 
      return '(?:' + word + '|' + exceptions[word] + ')'; 

     } else if (word.match(/(?:x|s|[cs]h)$/)) { 
      // Sibilants 
      return word + '(?:es)?'; 

     } else if (word.match(/[^f]f$/)) { 
      // Non-Geminate Labio-Dental Fricative (-f > -ves/-fs) 
      return '(?:' + word + 's?|' + word.replace(/f$/, 'ves') + ')'; 

     } else if (word.match(/[^aeiou]y$/)) { 
      // Close-Front Unround Pure Vowel (-Cy > -Cies) 
      return '(?:' + word + '|' + word.replace(/y$/, 'ies') + ')'; 

     } else if (word.substr(-1) == 'o') { 
      // Mid-Back Round Vowel (-o > -oes/-os) 
      return word + '(?:e?s)?'; 

     } else { 
      // Otherwise 
      return word + 's?'; 
     } 
     }; 

    String.prototype.containsNoun = function(singularNoun) { 
    if (!isWord(singularNoun)) throw new TypeError('Invalid word'); 
    var check = new RegExp('\\b' + pluralise(singularNoun) + '\\b', 'gi'); 
    return check.test(this); 
    }; 

    String.prototype.pluralException = function(plural) { 
    if (!isWord(this) || !isWord(plural)) throw new TypeError('Invalid exception'); 

    var singular = this.toLowerCase(); 
    plural = plural.toLowerCase(); 

    if (!(singular in exceptions)) { 
     exceptions[singular] = plural; 
    } 
    }; 
})(); 

Rozciąga rodzimą String obiektu, więc go używać tak:

'Are there some foos in here?'.containsNoun('foo'); // True 

Zobacz the gist jakiegoś Quick- i-dirty testowanie jednostkowe wykonane w Node.js.

Powiązane problemy