正则表达式(3)
扫描 HREF
以下示例搜索输入字符串并输出所有 href="/“..."”值和它们在字符串中的位置。它执行此操作的方式为,首先构造编译的
在此示例中,元字符 \s 匹配任何空白字符,\S 匹配任何非空白字符。
[Visual Basic]
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 支持将匹配捕获到指定的槽中的语法 (?<name>...)。(槽可以用字符串或整数命名;但整数可以被更快地回调。)因此,同一字符串的所有替换匹配都可被定向到同一位置。如果出现冲突,放置到槽中的最后一个匹配将是成功的匹配。(但是,单个槽的多个匹配的完整列表是可用的。有关详细信息,请参见
更改日期格式
以下代码示例使用
[Visual Basic]
Function MDYToDMY(input As String) As String
Return Regex.Replace(input, _
"\b(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})\b", _
"${day}-${month}-${year}")
End Function
[C#]
String MDYToDMY(String input)
{
return Regex.Replace(input,
"\\b(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})\\b",
"${day}-${month}-${year}");
}
Regex 替换模式
本示例说明如何在 Regex.Replace 的替换模式中使用命名的反向引用。其中,替换表达式 ${day} 插入由 (?<day>...) 组捕获的子字符串。
有几种静态函数使您可以在使用正则表达式操作时无需创建显式正则表达式对象,而 Regex.Replace 函数正是其中之一。如果您不想保留编译的正则表达式,这将给您带来方便。
以下代码示例使用
[Visual Basic]
Function Extension(url As String) As String
Dim r As New Regex("^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/", _
RegexOptions.Compiled)
Return r.Match(url).Result("${proto}${port}")
End Function
[C#]
String Extension(String url)
{
Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/",
RegexOptions.Compiled);
return r.Match(url).Result("${proto}${port}");
}
示例:清理输入字符串
下面的代码示例使用静态 CleanInput 方法,清除掉在接受用户输入的窗体的文本字段中输入的可能有害的字符。CleanInput 在清除掉除 @、-(连字符)和 .(句点)以外的所有非字母数字字符后返回一个字符串。
[Visual Basic]
Function CleanInput(strIn As String) As String
' Replace invalid characters with empty strings.
Return Regex.Replace(strIn, "[^\w\.@-]", "")
End Function
[C#]
String CleanInput(string strIn)
{
// Replace invalid characters with empty strings.
return Regex.Replace(strIn, @"[^\w\.@-]", "");
}
下面的代码示例使用静态 IsValidEmail 方法返回 true,否则返回 false,但不采取其他任何操作。您可以使用 IsValidEmail,在应用程序将地址存储在数据库中或显示在 ASP.NET 页中之前,筛选出包含无效字符的电子邮件地址。
[Visual Basic]
Function IsValidEmail(strIn As String) As Boolean
' Return true if strIn is in valid e-mail format.
Return Regex.IsMatch(strIn, ("^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")
End Function
[C#]
bool IsValidEmail(string strIn)
{
// Return true if strIn is in valid e-mail format.
return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
浙公网安备 33010602011771号