【问题标题】:Match single word, with possible punctuation or pluralization at end (Regex)匹配单个单词,结尾可能有标点符号或复数形式(正则表达式)
【发布时间】:2013-01-29 07:27:11
【问题描述】:

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

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

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

要查找的单词:“bar”

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

"foo bar" //真

“富吧。” //真

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

“富酒吧。” //真

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

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

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

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

非常感谢您的帮助!

【问题讨论】:

  • 所以“child”不应该匹配“children”,对吗?
  • 是的,我不希望“child”匹配“children”。
  • 正则表达式很难做到多元化。 mouse/micecolossus/colossi 呢?
  • Frits,我不希望匹配这些类型的复数词。
  • 这些情况怎么样:in5barbares_randomĂbar

标签: javascript regex


【解决方案1】:
var rgx = new RegExp('\\b' + word + '(?:es|s)?\\b');
rgx.test(string);

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

【讨论】:

  • 这很好用!只需进行一项更改即可使其正常工作。将“正则表达式”更改为“正则表达式”。非常感谢 EP!
  • @StevenJenkins 哎呀,我在所有测试中都使用了RegExp,但我首先在答案中写了Regex
【解决方案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

请参阅the gist,了解在 Node.js 中完成的一些快速而简单的单元测试。

【讨论】:

    【解决方案3】:
    / (bar((e)?s)?)[ !?.]/
    

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 2022-08-02
      • 2016-06-21
      • 1970-01-01
      相关资源
      最近更新 更多