簡體   English   中英

標簽的正則表達式匹配

[英]Regular Expression Match for Tags

我需要使用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。

不用正則表達式即可:

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;
}

供您參考,我放棄了用於檢查重復標簽的正則表達式(規則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"));
    }

仍然歸功於塞德里克·比格農(Cedric Bignon)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM