如何仅使用给定字符匹配一个单词

时间:2015-05-23 13:39:21

标签: c# regex match

我试图找到一个正则表达式模式来匹配一个给定字符的单词。但每个角色只能使用一次。例如,如果我给出了" yrarbil " (库向后),它应该符合这些:

  • 文库
  • RAR
  • LIB
  • rarlib

但它不符合以下

  • libraryy(" y"使用次数超过给定次数)
  • 图书馆(" i"使用次数超过给定次数,而且" es"根本没有给出)

我已经四处搜索但最好能找到匹配一个单词的代码,但使用的字符数超过给定的次数。谢谢。

P.S:如果不能在正则表达式中完成(我可以看到它是一个菜鸟),那么以编程方式匹配这个单词的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

正则表达式不会为此而努力。一个解决方案是简单地计算列表中的字符。

例如在JavaScript中:



guess

function count(str){
  return str.split('').reduce(function(m,c){
     m[c] = (m[c]||0)+1;
     return m;
  },{})
}
function check(str, reference){
   var ms = count(str), mr = count(reference);
   for (var k in ms) {
     if (!(ms[k]<=mr[k])) return false;
   }
   return true;
}

// what follows is only for demonstration in a snippet
$('button').click(function(){
  $('#r').text(check($('#a').val(), "library") ? "OK":"NOT OK");
})
&#13;
&#13;
&#13;

答案 1 :(得分:1)

“图书馆”令人困惑,因为它有2窝r。但是从我看来它是可以解决的。

轻松创建map<char, int>这将存储模式中每个字符的计数。然后我们将为要检查的单词生成map<char, int>,它还将包含每个char的计数,然后迭代地图,如果任何char的计数多于它不匹配的模式映射中的相同char,如果根本找不到那么它也不匹配。

根据需要C#中的代码 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text; 使用System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static bool Match(string pattern, string toMatch)
        {
            Dictionary<char, int> patternMap = new Dictionary<char, int>();
            Dictionary<char, int> toMatchMap = new Dictionary<char, int>();

            foreach (char ch in pattern)
            {
                if (patternMap.ContainsKey(ch))
                    ++patternMap[ch];
                else
                    patternMap[ch] = 1;
            }
            foreach (char ch in toMatch)
            {
                if (toMatchMap.ContainsKey(ch))
                    ++toMatchMap[ch];
                else
                    toMatchMap[ch] = 1;
            }

            foreach (var item in toMatchMap)
            {
                if (!patternMap.ContainsKey(item.Key) || patternMap[item.Key] < item.Value)
                    return false;
            }
            return true;
        }
        static void Main(string[] args)
        {
            string pattern = "library";
            string[] test = { "lib", "rarlib", "rarrlib", "ll" };
            foreach (var item in test)
            {
                if(Match(pattern, item))
                    Console.WriteLine("Match item : {0}", item);
                else
                    Console.WriteLine("Failed item : {0}", item);
            }
            Console.ReadKey();

            /*
Match item : lib
Match item : rarlib
Failed item : rarrlib
Failed item : ll

             */
        }
    }
}

答案 2 :(得分:0)

我不明白为什么你想用一个非常简单直接的解决方案时使用regexp来做这件事。

您只需计算每个字母在给定单词中出现的次数,以及您测试的单词。然后检查测试单词中的每个字母出现的次数不会超过给定单词。

for ch in given_word
    cnt[ch]++
for ch in test_word
    cnt[ch]--
for ch='a'..'z'
    if cnt[ch]<0
        answer is no
if for all leters cnt[ch]>=0 
    answer is yes