正则表达式应用--扫描 HREF,提取 URL 信息

2009年3月20日星期五

正则表达式应用--扫描 HREF,提取 URL 信息

以下示例搜索输入字符串并输出所有 href=“...”值和它们在字符串中的位置。它执行此操作的方式为,首先构造编译的 Regex 对象,然后使用 Match 对象来循环访问字符串中的所有匹配。

在此示例中,元字符 \s 匹配任何空白字符,\S 匹配任何非空白字符。


引用:
--------------------------------------------------------------------------------
Sub DumpHrefs(inputString As String)
Dim r As Regex
Dim m As Match

r = New Regex("href\s*=\s*(?:""(?<1>[^""]*)""|(?<1>\S+))", _
RegexOptions.IgnoreCase Or RegexOptions.Compiled)

m = r.Match(inputString)
While m.Success
Console.WriteLine("Found href " & m.Groups(1).Value _
& " at " & m.Groups(1).Index.ToString())
m = m.NextMatch()
End While
End Sub
[C#]
void DumpHrefs(String inputString)
{
Regex r;
Match m;

r = new Regex("href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))",
RegexOptions.IgnoreCase|RegexOptions.Compiled);
for (m = r.Match(inputString); m.Success; m = m.NextMatch())
{
Console.WriteLine("Found href " + m.Groups[1] + " at "
+ m.Groups[1].Index);
}
}
--------------------------------------------------------------------------------


编译模式
在开始搜索字符串的循环前,此代码示例创建 Regex 对象来存储编译模式。因为需要花一些时间来分析、优化和编译正则表达式,所以在循环外执行这些任务,以便不重复这些任务。

Regex 类的实例是不可变的;每一实例对应于单个模式并且是无状态的。这将允许由不同的函数甚至是不同的线程共享单个 Regex 实例。

匹配结果类
搜索的结果存储在 Match 类中,这提供对该搜索提取的所有子字符串的访问。因为该类还记忆所搜索的字符串和所使用的正则表达式,所以它还可以使用这些字符串和表达式来在上一次搜索结束的地方开始另一个搜索。

显式命名的捕获
在传统的正则表达式中,捕获括号是自动按顺序编号的。这导致了两个问题。首先,如果通过插入或移除一组括号修改了一个正则表达式,则必须重写所有引用编号捕获的代码以反映新的编号。其次,因为不同的括号组经常被用来为可接受的匹配提供两个可替换的表达式,所以可能比较难于确定哪一个可替换的表达式实际返回了结果。

为了解决这些问题,Regex 支持将匹配捕获到指定的槽中的语法 (?...)。(槽可以用字符串或整数命名;但整数可以被更快地回调。)因此,同一字符串的所有替换匹配都可被定向到同一位置。如果出现冲突,放置到槽中的最后一个匹配将是成功的匹配。(但是,单个槽的多个匹配的完整列表是可用的。有关详细信息,请参见 Group.Captures 集合。)
---------------------------------------------------------------------
提取 URL 信息:
以下代码示例使用 Match.Result 来从 URL 提取协议和端口号。例如,“http://www.contoso.com:8080/letters/readme.html”将返回“http:8080”。

[Visual Basic]
Function Extension(url As String) As String
Dim r As New Regex("^(?\w+)://[^/]+?(?:\d+)?/", _
RegexOptions.Compiled)
Return r.Match(url).Result("${proto}${port}")
End Function
[C#]
String Extension(String url)
{
Regex r = new Regex(@"^(?\w+)://[^/]+?(?:\d+)?/",
RegexOptions.Compiled);
return r.Match(url).Result("${proto}${port}");
}

0 评论:

发表评论