7

我在 Regex 方面一直在进步,但我想出了一些超出我目前能力范围的东西。

我想构建一个函数来测试(返回真或假)来测试是否在字符串中找到一个单词。但是,如果在另一个词中找到了这个词,我不希望有一个肯定的匹配。我还想建立检查复数的可能性。

以下是我希望得到的结果的一些示例:

要查找的单词: “bar”

“要搜索的字符串”//它应该返回的内容

“富吧”//真

“富吧。” //真的

“富吧!” //true(对于“bar”之前或之后的任何其他标点符号也是如此)

“美式酒吧。” //真的

“foo 裸露。” //true(即使bares与bars有不同的含义,我也可以返回true,因为我需要检查以“es”复数形式的单词,并且我不希望构建一个正则表达式来知道哪些单词复数用“s”和“es”)

"my name is bart simpson" //false (bar 实际上是 "bart" 的一部分)

“巴特辛普森去了酒吧。” //真的

我将使用 javascript/jquery 来检查匹配项

非常感谢你的帮忙!

4

3 回答 3

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

这将返回true您在请求中指定的所有字符串。 \b表示“单词边界”,我认为它是\W(包括句点和感叹号)中的任何字符以及字符串的开头或结尾。

于 2013-02-13T18:08:24.847 回答
2

这已经得到了回答和接受,但我想我会提供一种稍微过度设计的方法,可以更好地匹配复数形式。除此之外,它使用与@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;
    }
  };
})();

它扩展了本机String对象,因此您可以像这样使用它:

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

有关在 Node.js 中完成的一些快速而简单的单元测试,请参阅要点。

于 2013-02-14T11:58:32.163 回答
1
/ (bar((e)?s)?)[ !?.]/

取决于您到底需要什么,这可能会起作用。由于重叠的空格,它不会在字符串“bars bars”中找到两个小节。

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

自 js1.5 以来,这应该与“bars bar”(两个匹配项)一起使用,现在所有浏览器都支持它。

于 2013-02-13T17:58:32.310 回答