一个标题的正则表达式匹配

4

我需要使用C#编写一个正则表达式来匹配标题,以下是要求:

  1. 标题必须存在(长度>0);
  2. 最大256个字符(长度<= 256);
  3. 没有字符被禁止,但只包含空格是不允许的(仅包含空格的标题是不允许的);
  4. 不能有前导或尾随空格;

我已经有了以下正则表达式:

^.{1,256}$

那么我该如何满足规则3呢?
编辑:
1. 更清晰地解释了规则3; 2. 我添加了Mario回答中的规则4。

我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
嗯,有时候正则表达式在不同的编程语言中会有稍微不同的语法,所以我认为在标题中加上 C# 标签是必要的。 - Peter Lee
我们在 [so] 上使用标签来实现这一点。标题可以作为标题。有点像 [so] 的“关注点分离”思想。 - John Saunders
4个回答

2
使用(?=pattern)
@"^(?=.*\S).{1,256}$"
(?=pattern)表示指定的模式紧跟在此位置之后,如果在字符串开头匹配模式.*\S并且整个字符串匹配模式^.{1,256}$,则正则表达式匹配成功。

@SLaks 在第三条规则中解释了只有空格是非法的。 - Cédric Bignon
这不是他的意思。他只想拒绝完全为空格的字符串。 - SLaks
@SLaks 我没有这样解释规则。 - Cédric Bignon

2

您需要使用零宽断言:

@"^(?=.*\S).{1,256}$"

(?=.*\S) 匹配以非空白字符结尾的任何字符序列,但不影响匹配的其余部分。


2

我建议完全跳过正则表达式,因为你可以通过两个简单的步骤硬编码字符串清理和验证:

  • 使用String.Trim(null)删除所有前导/尾随空格。
  • 比较剩余字符串的长度。
  • 将第一个字符大写(如果需要)。

这样做的原因是,仅由空格组成的名称将被修剪为0长度。 此外,这避免了使用标题,例如" Let's go!"


1
从技术上讲,这不是他要求的;这将接受由空格包围的256个字符。 - SLaks
在我看来,这取决于你是否愿意接受像 test 这样的名称(或者更喜欢将它们“修复”)。如果你想保留前导/尾随空格,你可以先进行长度检查,然后确定在 Trim() 之后剩下的内容是否仍然长于0。 - Mario

0

虽然我的答案符合我的问题,但是功劳仍应归于其他人(我要么点赞并选择为正确答案),因为我在他们的回答之后编辑了我的问题。

=====================

我终于想出了一个纯正则表达式的解决方案(没有任何额外步骤)

^(\S|\S.{0,254}\S)$

(虽然我不明白为什么括号()很重要)
以下测试案例通过:
    [TestMethod]
    public void CheckTitleTest()
    {
        // Empty
        Assert.IsFalse(CheckTitle(@""));

        // A whitespace
        Assert.IsFalse(CheckTitle(@" "));

        // Multiple whitespace only
        // http://msdn.microsoft.com/en-us/library/t809ektx.aspx
        Assert.IsFalse(CheckTitle("  \t \n \u1680"));

        // Leading whitespaces
        Assert.IsFalse(CheckTitle("  \tabc"));

        // Trailing whitespaces
        Assert.IsFalse(CheckTitle("abc\t "));

        // Leading and trailing whitespaces
        Assert.IsFalse(CheckTitle("  \tabc\t "));

        // Too long: 257 character
        Assert.IsFalse(CheckTitle(@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/*"));

        // A normal title
        Assert.IsTrue(CheckTitle(@"This is a normal title"));
        Assert.IsTrue(CheckTitle(@"This is a normal title."));

        // 256 characters
        Assert.IsTrue(CheckTitle(@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"));

        // A very simple title
        Assert.IsTrue(CheckTitle(@"A"));
        Assert.IsTrue(CheckTitle(@"!"));
        Assert.IsTrue(CheckTitle(@"\"));
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接