C# Regex(2)

  • 当使用大量的正则表达式进行静态方法调用时。 默认情况下,正则表达式引擎将缓存 15 个最近使用的静态正则表达式。 如果应用程序使用的静态正则表达式超过 15 个,则必须重新编译某些正则表达式。 为了防止执行此类重新编译,您可以将 Regex.CacheSize 属性增加到适当的值。

  • 当应用程序使用先前已编译的正则表达式实例化新的 Regex 对象时。 例如,下面的代码定义一个正则表达式,以定位某个文本流的各个行中重复的单词。 虽然本示例使用一个正则表达式,但它将实例化一个新的 Regex 对象来处理每行文本。 这将导致在每次循环迭代时都重新编译此正则表达式。

    StreamReader sr = new StreamReader(filename);
    string input;
    string pattern = @"\b(\w+)\s\1\b";//\b:从单词边界开始匹配。
    while (sr.Peek() >= 0)
    {
    input = sr.ReadLine();
    Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
    MatchCollection matches = rgx.Matches(input);
    if (matches.Count > 0)
    {
    Console.WriteLine("{0} ({1} matches):", input, matches.Count);
    foreach (Match match in matches)
    Console.WriteLine(" " + match.Value);
    }
    }
    sr.Close();

    若要防止重新编译,此应用程序应实例化一个 Regex 对象,该对象供需要它的所有代码访问,如以下重写示例所示

    StreamReader sr = new StreamReader(filename);
    string input;
    string pattern = @"\b(\w+)\s\1\b";//\b:从单词边界开始匹配。
    Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);

    while (sr.Peek() >= 0)
    {
    input = sr.ReadLine();
    MatchCollection matches = rgx.Matches(input);
    if (matches.Count > 0)
    {
    Console.WriteLine("{0} ({1} matches):", input, matches.Count);
    foreach (Match match in matches)
    Console.WriteLine(" " + match.Value);
    }
    }
    sr.Close();


执行正则表达式操作

无论您决定是实例化一个 Regex 对象并调用其方法,还是调用静态方法,Regex 类都将提供以下模式匹配功能:

  • 验证匹配。 您可以调用 IsMatch 方法以确定是否存在匹配。

  • 检索单个匹配。 您可以调用 Match 方法来检索 Match 对象,该对象表示字符串或字符串一部分中的第一个匹配项。 后续匹配项可以通过调用 Match.NextMatch 方法进行检索。

  • 检索所有匹配。 您可以调用 Matches 方法来检索 System.Text.RegularExpressions.MatchCollection 对象,该对象表示在字符串或字符串一部分中找到的所有匹配项。

  • 替换匹配的文本。 您可以调用 Replace 方法来替换匹配的文本。 此替换文本还可通过正则表达式来定义。 此外,某些 Replace 方法包括一个 MatchEvaluator 参数,该参数使您能够以编程方式定义替换文本。

  • 创建字符串数组,该数组是由输入字符串的各个部分构成。 您可以调用 Split 方法,在正则表达式定义的位置拆分输入字符串。

除了其匹配模式方法之外,Regex 类还包括几种特殊用途的方法:

  • Escape 方法可以对任何在正则表达式或输入字符串中可能被解释为正则表达式运算符的字符进行转义。

  • Unescape 方法移除这些转义字符。

  • CompileToAssembly 方法创建一个包含预定义正则表达式的程序集。 .NET Framework 在 System.Web.RegularExpressions 命名空间中包含这些特殊用途的程序集的示例。

下面的示例使用正则表达式检查字符串中重复出现的词。 正则表达式 \b(?<word>\w+)\s+(\k<word>)\b 可按下表中的方式解释。

模式

说明

\b

从单词边界开始匹配。

(?<word>\w+)

匹配一个或多个单词字符(最多可到单词边界)。 将此捕获组命名为 word

\s+

匹配一个或多个空白字符。

(\k<word>)

匹配名为 word 的捕获组。

\b

与字边界匹配。

using System;
using System.Text.RegularExpressions;

public class Test
{
//统计字符串中重复出现的单词
public static void Main ()
{

// Define a regular expression for repeated words.
Regex rx = new Regex(@"\b(?<word>\w+)\s+(\k<word>)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase);

// Define a test string.
string text = "The the quick brown fox fox jumped over the lazy dog dog.";

// Find matches.
MatchCollection matches = rx.Matches(text);

// Report the number of matches found.
Console.WriteLine("{0} matches found in:\n {1}",
matches.Count,
text);

// Report on each match.
foreach (Match match in matches)
{
GroupCollection groups = match.Groups;
Console.WriteLine("'{0}' repeated at positions {1} and {2}",
groups["word"].Value,
groups[0].Index,
groups[1].Index);
}

}

}
// The example produces the following output to the console:
// 3 matches found in:
// The the quick brown fox fox jumped over the lazy dog dog.
// 'The' repeated at positions 0 and 4
// 'fox' repeated at positions 20 and 25
// 'dog' repeated at positions 50 and 54


下面的示例演示如何使用正则表达式来检查字符串是表示货币值还是具有表示货币值的正确格式。 在这种情况下,将从用户的当前区域性的 NumberFormatInfo.CurrencyDecimalSeparatorCurrencyDecimalDigitsNumberFormatInfo.CurrencySymbolNumberFormatInfo.NegativeSignNumberFormatInfo.PositiveSign 属性中动态生成正则表达式。 系统的当前区域性是否能 EN-US 产生的正则表达式是 ^\s*[\+-]? \s? \$? \s?(\d*\.? \d{2}?){1}$. 此正则表达式可按下表中所示进行解释。

模式

说明

^

在字符串的开头处开始。

\s*

匹配零个或多个空白字符。

[\+-]?

匹配正号或负号的零个或一个匹配项。

\s?

匹配零个或一个空白字符。

\$?

匹配美元符号的零个或一个匹配项。

\s?

匹配零个或一个空白字符。

\d*

匹配零个或多个十进制数字。

\.?

匹配零个或一个小数点符号。

\d{2}?

匹配两位十进制数零次或一次。

(\d*\.? \d{2}?){1}

至少匹配一次由小数点符号分隔整数和小数的模式。

$

匹配字符串的末尾部分。

在这种情况下,正则表达式假定有效货币字符串不包括组分隔符,并且此字符串既没有小数数字,也没有由当前区域性的 CurrencyDecimalDigits 属性定义的小数位数。

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
// Get the current NumberFormatInfo object to build the regular
// expression pattern dynamically.
NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo;

// Define the regular expression pattern.
string pattern;
pattern = @"^\s*[";
// Get the positive and negative sign symbols.
pattern += Regex.Escape(nfi.PositiveSign + nfi.NegativeSign) + @"]?\s?";
// Get the currency symbol.
pattern += Regex.Escape(nfi.CurrencySymbol) + @"?\s?";
// Add integral digits to the pattern.
pattern += @"(\d*";
// Add the decimal separator.
pattern += Regex.Escape(nfi.CurrencyDecimalSeparator) + "?";
// Add the fractional digits.
pattern += @"\d{";
// Determine the number of fractional digits in currency values.
pattern += nfi.CurrencyDecimalDigits.ToString() + "}?){1}$";

Regex rgx = new Regex(pattern);

// Define some test strings.
string[] tests = { "-42", "19.99", "0.001", "100 USD",
".34", "0.34", "1,052.21", "$10.62",
"+1.43", "-$0.23" };

// Check each test string against the regular expression.
foreach (string test in tests)
{
if (rgx.IsMatch(test))
Console.WriteLine("{0} is a currency value.", test);
else
Console.WriteLine("{0} is not a currency value.", test);
}
}
}
// The example displays the following output:
// -42 is a currency value.
// 19.99 is a currency value.
// 0.001 is not a currency value.
// 100 USD is not a currency value.
// .34 is a currency value.
// 0.34 is a currency value.
// 1,052.21 is not a currency value.
// $10.62 is a currency value.
// +1.43 is a currency value.
// -$0.23 is a currency value.


因为本示例中的正则表达式是动态生成的,所以在设计时我们不知道正则表达式引擎是否可能将当前区域性的货币符号、小数符号或正号及负号错误解释为正则表达式语言运算符。 若要防止任何解释错误,本示例将每个动态生成的字符串传递到 Escape 方法。

posted @ 2011-04-26 16:37  Kingdom_0  阅读(584)  评论(0编辑  收藏  举报