【问题标题】:Regex without taking care of escape codes不考虑转义码的正则表达式
【发布时间】:2016-05-19 16:31:45
【问题描述】:

我的问题涉及正则表达式,应该很简单(我希望)。

我想验证这样的字符串(netsh cmd 输出):

"\r\nR‚servations d'URLÿ:\r\n--------------------\r\n\r\n    URL r‚serv‚e            : https://+:443/SomeWebSite/ \r\n        Utilisateurÿ: AUTORITE NT\\SERVICE R\u0090SEAU\r\n            \u0090couterÿ: Yes\r\n            D‚l‚guerÿ: Yes\r\n            SDDLÿ: D:(A;;GA;;;NS) \r\n\r\n\r\n"

使用这种模式:

"URL .+https:\/\/\+:443\/SomeWebSite\/.+Yes.+Yes.+SDDL.+"

所以,我打算检测这种字符串(xxxxx是什么(+)):

xxxxxURLxxxxxhttps://+:443/SomeWebSite/xxxxxYesxxxxxYesxxxxxSDDLxxxx

我用 C# 编写了这段代码来做这件事,但我的表达仍然不起作用:

string output = "\r\nR‚servations d'URLÿ:\r\n--------------------\r\n\r\n    URL r‚serv‚e            : https://+:443/SomeWebSite/ \r\n        Utilisateurÿ: AUTORITE NT\\SERVICE R\u0090SEAU\r\n            \u0090couterÿ: Yes\r\n            D‚l‚guerÿ: Yes\r\n            SDDLÿ: D:(A;;GA;;;NS) \r\n\r\n\r\n";
output = output.Replace(Environment.NewLine, ""); //==> output2=="R‚servations d'URLÿ:-----------
Regex testUrlOpened = new Regex(output, RegexOptions.Singleline);
MessageBox.Show(testUrlOpened.IsMatch(@"URL").ToString()); // ==> False
MessageBox.Show(testUrlOpened.IsMatch(@".+URL.+").ToString()); // ==> False
MessageBox.Show(testUrlOpened.IsMatch(@"URL .+https:\/\/\+:443\/SomeWebSite\/.+Yes.+Yes.+SDDL.+").ToString()); // ==> False

所以我想我在 c# 中遇到了正则表达式的另一个问题...... 可能是编码问题?

感谢您的帮助!

弗朗索瓦

【问题讨论】:

    标签: c# regex string parsing encoding


    【解决方案1】:

    首先删除字符串中预期的转义码。根据您的使用场景,最好将它们全部删除(C# escape codes)

    output = output.Replace('\n').Replace('\r').Replace('\t') 
    

    现在你有一个单行字符串,你可以做正则表达式匹配

    .+URL.+https:\/\/.+:443\/SomeWebSite\/.+Yes.+Yes.+SDDL.+
    

    请注意以下事项: 1- ^ 和 $ 表示匹配字符串的确切开头和结尾。如果你在行中有目标字符串,使用这些将导致匹配失败。

    2- 您需要转义必要的正则表达式字符。 3-要匹配“除换行符以外的任何字符一次或多次”,请使用 .+

    希望对你有帮助

    【讨论】:

    • 嗨 Moataz,感谢您的帮助...距离我上次使用正则表达式已有两年... :)
    • 欢迎。您可能想使用:regexr.com。我发现它对调试和理解我的正则表达式很有帮助。
    • 不要依赖正则表达式来测试 .NET 正则表达式,它不支持 .NET 正则表达式语法。检查[\w-[_]]+ 正则表达式和regexstorm new_word
    • 但最后,我还有另一个问题......即使模式“.+URL.+”不匹配......我已经编辑了我原来的问题......
    • 知道了...我已经交换了输入和正则表达式... :(
    【解决方案2】:

    您可以使用Regex.Unescape 取消转义字符串,然后进行正则表达式匹配:

    var output = @"\r\nR‚servations d'URLÿ:\r\n--------------------\r\n\r\n    URL r‚serv‚e            : https://+:443/SomeWebSite/ \r\n        Utilisateurÿ: AUTORITE NT\\SERVICE R\u0090SEAU\r\n            \u0090couterÿ: Yes\r\n            D‚l‚guerÿ: Yes\r\n            SDDLÿ: D:(A;;GA;;;NS) \r\n\r\n\r\n";
    output = Regex.Unescape(output).Dump();
    
    var foundUrl = Regex.IsMatch(output, @"URL .+ https://\+:443/SomeWebSite/.+YES.+YES.+SDDL.+");
    

    【讨论】:

      【解决方案3】:

      + 表示 1 个或多个上述模式,如果我们将匹配 anything 的模式 (.|\n) 放在那些 + 的前面,你会全部设置,无需删除或考虑转义码。

      ^(.|\n)+URL(.|\n)+https://(.|\n)+:443/SomeWebSite/(.|\n)+Yes(.|\n)+Yes(.|\n)+SDDL(.|\n)+$

      编辑:做这样的事情而不是首先清理你的字符串的风险是你可能会得到误报,因为可能有任何字符分隔匹配项,所有这个正则表达式所做的是确保字符串中的某个位置,按顺序,是字符串

      "URL", "https://", ":443/SomeWebSite/", "Yes", "Yes", "SDDL"
      

      【讨论】:

      • 谢谢,我认为删除输入字符串中的“\r\n”更容易,但想法很有趣。
      【解决方案4】:

      如此简单。最后一个问题是由于 reg 表达式放入 Regex 构造函数并在 IsMatch 方法中输入字符串... :( 所以最终的代码是:

      string output = "\r\nR‚servations d'URLÿ:\r\n--------------------\r\n\r\n    URL r‚serv‚e            : https://+:443/SomeWebSite/ \r\n        Utilisateurÿ: AUTORITE NT\\SERVICE R\u0090SEAU\r\n            \u0090couterÿ: Yes\r\n            D‚l‚guerÿ: Yes\r\n            SDDLÿ: D:(A;;GA;;;NS) \r\n\r\n\r\n";
      output = output.Replace(Environment.NewLine, ""); //==> output2=="R‚servations d'URLÿ:-----------
      Regex testUrlOpened = new Regex((@"URL .+https:\/\/\+:443\/SomeWebSite\/.+Yes.+Yes.+SDDL.+", RegexOptions.Singleline);
      MessageBox.Show(testUrlOpened.IsMatch(output).ToString()); // ==> True!!!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-18
        • 2014-10-20
        • 2012-12-05
        • 2022-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多