【问题标题】:Regex help needed not working for me正则表达式帮助不需要为我工作
【发布时间】:2013-08-20 01:43:05
【问题描述】:

我有一个源字符串

<img src="./CaptchaServlet?rd=htb54m" class="flt"  id="captcha" height="33" width="110"/>

我想提取CaptchaServlet?rd=xxxxxx"之间的数据。

我试过但没有工作请任何人帮助我,我的正则表达式如下

r = New Regex("CaptchaServlet?rd=*(.+?)""", RegexOptions.IgnoreCase Or RegexOptions.Compiled)

【问题讨论】:

标签: .net regex vb.net


【解决方案1】:

说明

您所写的表达式CaptchaServlet?rd=*(.+?)"" 有几个错误:

  • 第一个? 表示使前面的t 可选。我认为您确实打算将问号作为文字问号,因此您需要将其转义为\?
  • 等号后面的* 也意味着允许= 出现零次或多次直到无穷大。这有点模棱两可,并且鉴于您的源字符串可能有 1 或 0 个等号,那么您可能希望将 =* 替换为 =?,这只是使 = 可选,

我个人会重写表达式以主动避免在 HTML 中使用正则表达式和模式匹配时出现的一些常见问题。我的表达是:

  • 捕获src属性值
  • 适用于双引号、单引号和不带引号的值
  • 避免棘手的边缘情况,这些情况通常会使简单的表达式出错

&lt;img(?=\s|&gt;)(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?\ssrc=(['"]?)(.*?)\1(?:\s|&gt;))(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*&gt;

或者,如果您只想提取 rd 查询字符串值,您可以使用:&lt;img(?=\s|&gt;)(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?\ssrc=(['"]?)\.\/CaptchaServlet\?rd=(.*?)\1(?:\s|&gt;))(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*&gt;。这会将 xxxxxx 放入捕获组 2

示例

Live Demo

示例文本

注意前两个图像标签有一些非常困难的边缘情况

<img onmouseover=' img = 10; src="NotYourImage.png" ; if (3 <img && src="NotYourImage.png" && 6>3) { funRotate(src) ; } ; ' src="ImageYouAreLookingFor.png">
<img onmouseover=' src="NotTheDroidsYouAreLookingFor.png" ; if (x > 3) { funRotate(src); } ' src="http://another.example/picture.png">
<img src="./CaptchaServlet?rd=htb54m" class="flt" id="captcha" height="33" width="110"/>

VB.Net 示例

Imports System.Text.RegularExpressions
Module Module1
  Sub Main()
    Dim sourcestring as String = "replace with your source string"
    Dim re As Regex = New Regex("<img(?=\s|>)(?=(?:[^>=]|='[^']*'|=""[^""]*""|=[^'""][^\s>]*)*?\ssrc=(['""]?)\.\/CaptchaServlet\?rd=(.*?)\1(?:\s|>))(?:[^>=]|='[^']*'|=""[^""]*""|=[^'""][^\s>]*)*>
",RegexOptions.IgnoreCase OR RegexOptions.IgnorePatternWhitespace OR RegexOptions.Multiline OR RegexOptions.Singleline)
    Dim mc as MatchCollection = re.Matches(sourcestring)
    Dim mIdx as Integer = 0
    For each m as Match in mc
      For groupIdx As Integer = 0 To m.Groups.Count - 1
        Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames(groupIdx), m.Groups(groupIdx).Value)
      Next
      mIdx=mIdx+1
    Next
  End Sub
End Module

匹配项

第 0 组获取整个图像标签
第 1 组获取用于包围 src 属性的引号,用于确保匹配正确的结束引号
第 2 组获取 src 值,或者如果您使用上面的备用正则表达式,将只收到 rd 查询字符串

[0][0] = <img onmouseover=' img = 10; src="NotYourImage.png" ; if (3 <img && src="NotYourImage.png" && 6>3) { funRotate(src) ; } ; ' src="ImageYouAreLookingFor.png">
[0][1] = "
[0][2] = ImageYouAreLookingFor.png

[1][0] = <img onmouseover=' src="NotTheDroidsYouAreLookingFor.png" ; if (x > 3) { funRotate(src); } ' src="http://another.example/picture.png">
[1][1] = "
[1][2] = http://another.example/picture.png

[2][0] = <img src="./CaptchaServlet?rd=htb54m" class="flt" id="captcha" height="33" width="110"/>
[2][1] = "
[2][2] = ./CaptchaServlet?rd=htb54m

【讨论】:

    【解决方案2】:

    试试这个:

    CaptchaServlet\?rd=[^"]*
    

    ...只要双引号从不作为数据的一部分出现,这将起作用。 :)

    我强烈建议您查看http://regexhero.net/,它会在您测试 .net 正则表达式时真正帮助您。

    编辑:改进了正则表达式。之前它只适用于字母数字字符。

    【讨论】:

    • @Arun sankar 是因为引用吗?你只需要逃避它。
    猜你喜欢
    • 2012-11-30
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多