2013-02-03 143 views
2

我需要用C#编写的标签的正则表达式,这里是要求:正则表达式匹配的标签

  1. 标签是可选的;
  2. 最多9个标签;
  3. 无重复标签;
  4. 每个标签最多30个字符;
  5. 每个标签应该只包含合理的字符(如何定义?,我现在使用[\w-]);
  6. 标记由,分隔(在逗号为可选后,有或没有空格);
  7. 结尾,(有或没有一个空格)也是合法的。

我已经有这样的:

^(|[\w-]{1,30}(,\s?[\w-]{1,30}){0,8}(,\s?)?)$ 

我觉得这是很难满足所有的规则。特别是排除3.

编辑:

  1. 更新规则5,第6条;
  2. 应用规则7.
+0

我不认为需求3甚至可能只是正则表达式。虽然我可能是错的。 –

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 –

+0

而不是使用正则表达式,我会按''分割字符串,并逐个处理“标签”(例如,修剪空格,验证允许的字符,小写字母),对它进行排序并去除重复项。 –

回答

0

做没有正则表达式:

public static bool TryGetTags(string tagsInput, out string[] tags) 
{ 
    Regex regex = new Regex(@"^[\w_-]+$"); 

    tags = tagsInput.Split(',') // Rule 6 
        .Select(tag => tag.Trim()) 
        .ToArray(); 

    if (tags.Last() == "") 
     tags = tags.Take(tags.Length - 1).ToArray(); // Rule 7 

    if (tags.Any(tag => tag == "")) // (no empty tag allowed except last one) 
     return false; 

    if (tags.Length > 9) 
     return false; // Rule 2 

    if (tags.Any(tag => tag.Length > 30)) 
     return false; // Rule 4 

    if (tags.Distinct().Count() != tags.Length) 
     return false; // Rule 3 

    if (tags.Any(tag => !regex.IsMatch(tag))) 
     return false; // Rule 5 

    return true; 
} 
+0

没有正则表达式?那么什么是“正则表达式”? –

+0

我终于放弃了检查重复标签的正则表达式。对于其他规则,我仍然使用正则表达式。 –

0

供您参考,我放弃了正则表达式检查重复标签(第3条)。我仍然使用正则表达式来处理其他规则。

public static bool CheckTags(string tags) 
    { 
     if (!Regex.IsMatch(tags, @"^(|[\w-]{1,30}(,\s?[\w-]{1,30}){0,8}(,\s?)?)$")) 
      return false; 

     // Step 1: Check duplicated tags 
     // Step 1.1: Remove the whitespace first 
     tags = Regex.Replace(tags, @"\s+", @""); 
     string[] tagsArray = tags.Split(','); 

     // Step 1.2: Check if duplicated items exist 
     if (tagsArray.Distinct().Count() != tagsArray.Length) 
      return false; 

     return true; 
    } 

下面的测试案例通过:

[TestMethod] 
    public void CheckTagsTest() 
    { 
     // Whitespaces and commas only 
     Assert.IsFalse(CheckTags(" \t \n \u1680")); 
     Assert.IsFalse(CheckTags(" , , , ")); 
     Assert.IsFalse(CheckTags(",,,")); 
     Assert.IsFalse(CheckTags(",, ,")); 

     // 10 tags 
     Assert.IsFalse(CheckTags(@"tag0,tag1,tag2,tag3,tag4,tag5,tag6,tag7,tag8,tag9")); 

     // Duplicated tags 
     Assert.IsFalse(CheckTags(@"tag0,tag0")); 

     // A tag contains more than 30 characters 
     Assert.IsFalse(CheckTags(@"abcdefghijklmnopqrstuvwxyz0123*")); 

     // A tag contains invalid characters 
     Assert.IsFalse(CheckTags(@"tag!")); 
     Assert.IsFalse(CheckTags(@"tag*")); 

     // Tag separator contains more than one whitespaces 
     Assert.IsFalse(CheckTags(@"tag1, tag2, tag3")); 

     // Normal tags 
     Assert.IsTrue(CheckTags(@"tag1, tag2, tag3")); 
     Assert.IsTrue(CheckTags(@"tag1,tag2, tag3")); 
     Assert.IsTrue(CheckTags("tag1,tag2,\ttag3, tag4")); 

     // Ending tag separator is allowed 
     Assert.IsTrue(CheckTags("tag1,tag2,\ttag3, tag4,")); 
     Assert.IsTrue(CheckTags("tag1,tag2,\ttag3, tag4, ")); 

     // A tag contains 30 characters 
     Assert.IsTrue(CheckTags(@"abcdefghijklmnopqrstuvwxyz0123")); 

     // A tag contains '-' 
     Assert.IsTrue(CheckTags(@"T-shirt")); 
     Assert.IsTrue(CheckTags(@"-")); 

     // A tag contains '_' 
     Assert.IsTrue(CheckTags(@"T_shirt")); 
     Assert.IsTrue(CheckTags(@"_")); 

     // A tag contains chinese characters 
     Assert.IsTrue(CheckTags("\u4E2D")); 
    } 

信贷仍然去塞德里克BIGNON。