如何匹配除两个字符以外的所有内容?

vip*_*srz 1 c# regex

我需要匹配双花括号之间的所有字符,但我需要能够在一个大字符串中找到多个匹配项.

我一直在使用这个RegEx测试器,因为我在C#中这样做:http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx 此外,我有" SingleLine"检查因为我想要.匹配\n

以下是我匹配的字符串示例:

<div class="nest-1-2">
    <dl>
    <dt>Type:</dt>
    <dd>{{(Entity)Field Name.separator(, ) > [:Name:]}}</dd>
    <dt>At:</dt>
    <dd>{{(Entity)Field Name > [:Name:]}}</dd>
    <dt>Team:</dt>
    <dd>{{(Entity)Field Name.separator(, ) > [:First Name:] [:Last Name:]}}</dd>
    </dl>
</div>
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的正则表达式:

\{\{(?<field>[^>]*)?[ > ]?(?<looptemplate>[^\}\}].*)?\}\}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我希望所有内容都匹配所有文本到下一个}}这是匹配最后一个而不是下一个.所以我得到了一场比赛,这是从第一次{{到最后一次}}我尝试使用负向前看,(?!\}\})但这似乎对我不起作用.不幸的是,[^\}\}]它不匹配两个花括号,它只匹配一个.

我不是一个正则表达式的总菜鸟,但是这个人真的得到了我.我到处寻找答案,所以现在我希望有人可以帮助我.

我非常感谢专家的帮助.

Mar*_*der 5

一些东西:

  1. 您正在使用?包含的捕获组*.的*意思是"0次或更多次",所以基本上内容是已经可选的.使用?不做任何事情.

    \{\{(?<field>[^>]*)[ > ]?(?<looptemplate>[^\}\}].*)\}\}
    
    Run Code Online (Sandbox Code Playgroud)
  2. [ > ]匹配1个字符.无论是空间还是空间>.你可能意味着(?: > )(匹配" > "(忽略引号,否则SO不会渲染空格)并将它们组合在一起.

    \{\{(?<field>[^>]*)(?: > )?(?<looptemplate>[^\}\}].*)\}\}
    
    Run Code Online (Sandbox Code Playgroud)
  3. [^\}\}]是一样的[^\}].否定字符类不适用于字符串,它们仅适用于内部的每个字符,因此多次写入字符不会改变任何内容.我猜这就是为什么你尝试了负面的前瞻.这是对的,但你需要检查重复的每个字符的条件.否则你只检查一次,你looptemplate没有开始,\}\}但随后你开火了.*.所以组.和前瞻在一起:

    \{\{(?<field>[^>]*)(?: > )?(?<looptemplate>(?:(?!\}\}).)*)\}\}
    
    Run Code Online (Sandbox Code Playgroud)
  4. (?: > )是可选的,所以如果你有一些{{...}}不包含它(只有field部分你将得到与以前相同的问题,这次是[^>].在这里包括前瞻:

    \{\{(?<field>(?:(?!\}})[^>])*)(?: > )?(?<looptemplate>(?:(?!\}\}).)*)\}\}
    
    Run Code Online (Sandbox Code Playgroud)

顺便说一下,使用否定字符类或前瞻的替代方法是使用不合理的重复.如果你可以使用否定的字符类,那通常是可取的,因为它同样可读但通常比ungreedy修饰符更有效,因为它不需要回溯.在你的情况下,你必须使用前瞻(因为有一个你不想过去的两个连续字符的模式,而不是只有一个字符).在这种情况下,前瞻可能会通过避免回溯来抵消性能提升,而前瞻通常会略微降低可读性.所以你可能只想在这里不假思索地重复(附上重复量词?):

\{\{(?<field>(?:(?!\}})[^>])*)(?: > )?(?<looptemplate>.*?)\}\}
Run Code Online (Sandbox Code Playgroud)

请注意,您不能使用不合理的重复,field因为,(?: > )是可选的.这将导致field空虚和其他一切(包括可能" > "的匹配looptemplate.除非您将以下内容包括在>一个可选组中looptemplate:

\{\{(?<field>[^>]*?)(?: > (?<looptemplate>.*?))?\}\}
Run Code Online (Sandbox Code Playgroud)

最后一点说明.这只是一个品味问题,但让我向您介绍一种不同形式的逃避.许多元字符没有元字符当一个字符类中(只],-,^\现在仍是).所以你可以将你的元字符包装在一个字符类中以逃避它:

[{][{](?<field>[^>]*?)(?: > (?<looptemplate>.*?))?[}][}]
Run Code Online (Sandbox Code Playgroud)

正如我所说,只是一个建议,但对于大多数字符,我发现这比使用反斜杠更可读.