优化以下正则表达式

时间:2019-01-15 13:38:03

标签: c# regex

我需要一个正则表达式来匹配字符串,如下所示:

  • 必须以[开头
  • 必须包含]
  • 允许[]之间的任何字符(包括空格)
  • []之间必须至少包含一个字符
  • 允许在;之后有一个]。在;之后,允许所有个字符(尽管无关紧要,因为我不在乎)
  • 如果并且仅当;之后出现]时,空格(读取制表符,空格-尽管我可以保证不会出现\r\n\f\v ,这就是为什么我在下面的\s]之间使用;的原因。如果;之后没有],则] 必须是字符串的结尾。

我最终得到了以下通过正则表达式的正则表达式:^\[([^]]+)](?:\s+?;)?

速度是关键,因此,我希望改进正则表达式,以便在可能的情况下缩短一些周期。

我不太确定在这里使用前瞻是否有用。

编辑

例如:

[some;thing]-有效,具有捕获组some;thing

[something]-有效,具有捕获组something

[something]-无效,不是以[开头

[something] ;ojasodj-有效的捕获组something

[something] -无效,]后的空格没有;存在

[something];-有效的捕获组something

[]-无效,必须在[]之间包含至少一个字符

3 个答案:

答案 0 :(得分:2)

TL; DR:^\[([^]]+)](?:$|\s*;)

^\[([^]]+)]已经是匹配正则表达式第一部分的最佳方法,除非您可以删除捕获组。通过使用否定的字符类,可以避免在任何情况下都可能涉及任何.*.*?模式的情况下发生不必要的回溯。

要满足其他规则,您需要匹配字符串($)的末尾或可选空格和分号,因此应为(?:$|\s*;)。我将$放在第一位,因为这是较短的匹配项(因此可以更快地获得成功),但这也取决于您的数据(如果第二种情况是绝大多数,则放在第一位)。

完整模式为^\[([^]]+)](?:$|\s*;)

请注意,$后面可能是可选的\n,但是您的测试用例看起来不是多行的:)

答案 1 :(得分:0)

尝试此模式^\[[^\]]+\](?(?=\s*;)\s*;.*|$)

说明:

^\[[^\]]+\]将匹配字符串(^)开头方括号内的文本(其中]以外的至少一个字符)。

(?(?=\s*;)\s*;.*|$)-如果将方括号括起来后仅是空格和分号,则将它们匹配,否则请确保其在字符串($)的结尾。

Demo

答案 2 :(得分:0)

这是您可以使用代码代替的方法

public static bool IsValid(string str, out string capture)
{
    capture = null;

    // A null string is invalid
    if(str == null) return false;

    // An empty string is invalid
    if(str.Length == 0) return false;

    // A string that does not start with [ is invalid
    if(str[0] != '[') return false;
    int end = str.IndexOf(']');

    // A string that does not have a ] is invalid
    if(end == -1) return false;

    // A string that does not have anything between the [ and ] is invalid
    if(end == 1) return false;

    // if the ] is not the end of the string we need to look for a ;.
    if(end != str.Length -1)
    {
        bool semicolon = false
        for(int i = end + 1; i < str.Length; i++)
        {
            // ; found so we can stop looking at characters.
            if(str[i] == ';') 
            {
                semicolon = true;
                break;
            }

            // If non-whitespace is between the ] and ; the string is invalid
            if(!char.IsWhiteSpace(str[i])) return false;
        }

        // No ; found so the string is invalid
        if(!semicolon) return false;
    }

    // Capture the string between [ and ]
    capture = str.Substring(1,end - 1);
    return true;
}

显然不如正则表达式短,但运行速度可能更快。