【问题标题】:E-mail Regex causing catastrophic backtracking errorE-mail Regex causing catastrophic backtracking error
【发布时间】:2022-12-01 19:09:54
【问题描述】:

I am at the verge of loosing my mind over trying to fix an Email Regex i built:

It is almost perfect for what i need. It works in 99.9% of all cases.

But there is one case which causes a catastrophic backtracking error and i cannot fix my regex for it.

The "Email" causing a catastrophic backtrack error:

jasmin.martinez@tester.co.rolisa-brown.king@tester.co.ro

Yes, such emails do occur in the application i need this Regex for.

People enter multiple Emails in one field for some reason. I have no answer for why this occurs.

I need the Help of Wizards of Stack Overflow.

My Email Regex might block or not block some officially valid Emails but that is not the point here.

All i want is to fix the catastrophic backtracking Problem of my Regex. I do not want to change what it blocks or not. It works for what i need it to do.

Here is my Email Regex:

^[^\W_]+\w*(?:[.-]\w*)*[^\W_]+@[^\W_]+(?:[.-]?\w*[^\W_]+)*(?:\.[^\W_]{2,})$

How can i make this Regex fail quickly so it doesn't cause a catastrophic backtracking error.

Thank You very much.

【问题讨论】:

    标签: c# regex powershell backtracking


    【解决方案1】:

    You can use

    ^(?!_)w+(?:[.-]w+)*(?<!_)@[^W_]+(?>[.-]?w*[^W_])*.[^W_]{2,}$
    

    See the regex demo.

    The main idea is introducing an atomic group, (?&gt;[.-]?w*[^W_])* where backtracking is not allowed into the group pattern, and the re-vamped pattern before @: (?!_)w+(?:[.-]w+)*(?&lt;!_), that matches one or more word chars (while the first char cannot be a _) followed with zero or more sequences of . or - followed with one or more word chars that cannot end in _.

    The + in ^[^W_]+ is redundant, the next w* already matches the same chars, so it can be removed. The same idea is behind removing + in [^W_]@.

    Note that the last non-capturing group is redundant, I removed it.

    See the regex graphs:

    and from debuggex:

    【讨论】:

    • Thank You for the answer. There are 2 Problems. My originial Regex did not allow any special characters like german umlauts [äöüß]. This Regex does allow them. I also tried to visualize this Regex on jex.im but it failed to do so. I would need a regex diagram for my documentation. Do you know of a Visualizer capable of this?
    • @Zombievirus 1. Your original pattern matches any Unicode chars since w in .NET regex is Unicode aware. 2. I added the graph.
    • @Zombievirus I do not know of a regex visualizer that works that well for .NET compatible patterns. I just replace (?&gt; with (?: and (?&lt;! with (?! and then manually edited the text in Paint. But you might also like debuggex.com
    • Thank You Wiktor. I just double checked and you are right. My original Regex does allow for special charachters. May i ask if you know how i can allow only english charachters and [._-] in the email?
    • @Zombievirus You may simply compile the regex with RegexOptions.ECMAScript option. Then w will only match [A-Za-z0-9_].
    【解决方案2】:

    I would go with this one:

    ^[^W_][w.-]*[^W_]@[^W_][^W.-]*(?:[.-][^W.-]*[^W_])*[^W_].[^W_]{2,}$
    

    Demo: https://regex101.com/r/ecK9nB/1

    A comparison:

    before: ^[^W_]+w*(?:[.-]w*)*[^W_]+@[^W_]+              (?:[.-]?w*     [^W_]+)*(?:.[^W_]{2,})$
    after:  ^[^W_] [w.-]*        [^W_] @[^W_] [^W.-]*[^W_](?:[.-] [^W.-]*[^W_] )*   .[^W_]{2,} $
                    ^                    ^       ^^       ^            ^^       ^     ^  ^
                    ^                    ^       ^^       ^            ^^       ^     ^  No reason to use a group
                    ^                    ^       ^^       ^            ^^       ^     This quantifier was useless
                    ^                    ^       ^^       ^            ^^       ^If you want to match only letters before the possible [.-]
                    ^                    ^       ^^       ^            ^In order to allow w but not [.-]
                    ^                    ^       ^^       ^            Now, when you match [.-] there is no reason to make it optional
                    ^                    ^       ^^       If you want to match only letters before the possible [.-]
                    ^                    ^       ^In order to allow w but not [.-]
                    ^                    ^       Now this quantifier is useless
                    ^                    This quantifier was useless
                    w*(?:[.-]w*)* seems to be equivalent to [w.-]*
    

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 2023-01-30
      相关资源
      最近更新 更多