这是一个更普遍的问题,所以我使用的正则表达式并不重要,但这是我现在的问题:
(?<name>[^ ^\n]*)[ \n]+OBJECT IDENTIFIER(?<data>([^"]*"[^"]*?")*?[^"]*?)::=[ \n]*\{[ \n]*(?<parent>[^ ^\n]*) (?<oid>\w*)
此正则表达式中的主要内容是OBJECT IDENTIFIER
关键字,我是否可以首先忽略前面的(?<name>[^ ^\n]*)[ \n]+
进行正则表达式搜索,然后在正则表达式OBJECT IDENTIFIER
之后应该应用它整个表达到那个位置。
答案 0 :(得分:2)
编辑:
我认为通过这种模式,传输将找到固定的字符串位置,然后正则表达式引擎将向后搜索模式的开头,但它不能这样做。它并不像我想的那么聪明。
在这种情况下,您可以利用&#34;第一个字符串歧视&#34;加快识别写作这样的事情:
fixed string(?<=non-fixed subpattern, fixed string)
其中固定字符串位于模式的第一个位置,因此,允许传输使用Boyer-Moore算法来查找固定字符串的位置。
或者您可以尝试:
(?<=non-fixed subpattern)fixed string
我无法对其进行测试,但可能有一个简单的事实就是将非固定的子模式放在&#34;非固定的子模式中。在lookbehind里面允许传输选择在测试lookbehind或找到固定字符串之间找到匹配位置的最佳方法。但我不知道传输是否足够智能,这只是一个假设。
正如Qtax在注释中注意到的那样,子模式([^"]*"[^"]*?")*?[^"]*?
可能很慢,因为你使用了[^"]*?
之前的懒惰量词(组中的那个),它可以匹配相同的东西而不是小组的开始,这可以给一个空的比赛。
您可以使用后面的::=
来代替此子模式,并编写类似:[^:]+(?>:(?!:=)[^:]*)*
的内容,它不会导致回溯并仅使用贪婪的量词。 注意:如果您确实需要跳过双引号之间的::=
,则可以使用:[^:"]+(?>(?::(?!:=)|"[^"]*")[^:]*)*
。
另一个小优化:当你不需要捕获某些东西时,不要使用捕获组,而是在更好和可能时使用非捕获组或原子组。
结论,您可以测试这些模式(为自由间隔模式编写):
const string Pattern1 = @"\b OBJECT [ ] IDENTIFIER
(?<= (?<name> [^^\s]+ ) \s+ OBJECT [ ] IDENTIFIER)
(?<data> [^:]+(?> :(?!:=) [^:]* )* ) ::= \s* { \s*
(?<parent> [^^\s]+ ) \s+
(?<oid> \w+ )";
static Regex Reg1 = new Regex(Pattern1, RegexOptions.IgnorePatternWhitespace);
const string Pattern2 = @"(?<= (?<name> [^^\s]+ ) \s+)
\b OBJECT [ ] IDENTIFIER
(?<data> [^:]+(?> :(?!:=) [^:]* )* ) ::= \s* { \s*
(?<parent> [^^\s]+ ) \s+
(?<oid> \w+ )";
static Regex Reg2 = new Regex(Pattern2, RegexOptions.IgnorePatternWhitespace);
const string Pattern3 = @"\b OBJECT [ ] IDENTIFIER
(?<= (?<name> [^^\s]+ ) \s+ OBJECT [ ] IDENTIFIER)
(?<data> [^:"]+(?> (?: :(?!:=) | "" [^""]* "" ) [^:]* )* ) ::= \s* { \s*
(?<parent> [^^\s]+ ) \s+
(?<oid> \w+ )";
static Regex Reg3 = new Regex(Pattern3, RegexOptions.IgnorePatternWhitespace);
const string Pattern4 = @"(?<= (?<name> [^^\s]+ ) \s+)
\b OBJECT [ ] IDENTIFIER
(?<data> [^:"]+ (?> (?: :(?!:=) | "" [^""]* "" ) [^:]* )* ) ::= \s* { \s*
(?<parent> [^^\s]+ ) \s+
(?<oid> \w+ )";
static Regex Reg4 = new Regex(Pattern4, RegexOptions.IgnorePatternWhitespace);
注意:由于我没有看到你的数据,我认为每个命名的捕获都不能为空。如果不是这种情况,您只需将一些+
量词更改为*
。
注意2:如果您需要在代码中多次使用该模式,那么在使用和不使用compiled
正则表达式选项的情况下尝试这些模式会很有趣。
您不需要这样做,因为在正则表达式引擎工作之前存在预分析阶段。
此阶段称为&#34;传输&#34;并包含几个优化。其中一个优化包括首先从目标字符串中的模式中找到固定字符串,使用Boyer-Moore算法来减少正则表达式引擎的工作。