问题
给定字符串 "OUTPUT/FA(CIR1),TA(POS1__X),TA(POS1__Y),TA(POS1__Z),TA(POS1__D)"
现在需要取得括号中的内容,如 CIR1
、POS1__X
、POS1__Y
和POS1__Z
,如果我们使用字符串操作,肯定是可以取得,但是如果类似的操作比较频繁,我们完全可以使用正则表达式来完成。
正则模式定义
假定括号中的内容是数字、字母和下划线,那么我们可以使用以下字符来定义:[0-9a-zA-Z_]+
或者可以直接使用简化符号/w,变为 \w+
。因为我们要查找的带括号字符串,所以还需要将以上内容加上括号。在正则表达式中,如果要匹配括号是需要转义的,所以字符串变为:\(\w+\)
。
这时,带括号的字符串都会被匹配到。但是匹配到的内容是带括号的,比如 (CIR1)
,如果这样取的话,我们还需要将返回的结果再去一次括号,显然是多余的。我们还可以通过正则表达式提取指定的内容,使用括号即可(注:不需要转义),这时正则表达式的模式就变成了: \((\w+)\)
,即给 \w+
加上括号,这样即可指定取得括号中的内容,如 CIR1
。
特别注意一下括号的两种用法,对比如下:
- 原义:字符括号本身。
- 转义:用于取得括号中的内容。
在C#中使用Regex类
在C#中使用Regex类来处理正则表达式,使用的过程分为以下三步:
- 第1步 定义正则表达式模式(pattern):
Regex r = new Regex(@"\((\w+)\)");
- 第2步 对指定字符串进行匹配
var ms = r.Matches("OUTPUT/FA(CIR1),TA(POS1__X),TA(POS1__Y),TA(POS1__Z),TA(POS1__D)");
通过以上代码,在返回的结果ms
中,即可获得所需要的代码。 - 第3步 取出匹配到的内容
返回的结果是一个集合,有多个匹配,我们可以对其中某一个匹配进行操作,如Match m = ms.ToArray()[0];
,此时 我们可以使用m.Groups
获得匹配到的内容。由于在正则模式中可以定义多个括号,所以 Groups 中会有多个内容,其第0个元素表示表示所有的选中内容,而第1个起,表示第1个括号中的内容,以此类推,比如m.Groups[1]
表示CIR1
。
源代码和运行结果
首先,我们看下使用 \((\w+)\)
对 OUTPUT/FA(CIR1),TA(POS1__X),TA(POS1__Y),TA(POS1__Z),TA(POS1__D)
匹配后的运行结果:
------------ Original String ----------
OUTPUT/FA(CIR1),TA(POS1__X),TA(POS1__Y),TA(POS1__Z),TA(POS1__D)
------------ Regex String ----------
\((\w+)\)
------------ Matches ----------
Index=9 Value=(CIR1) Groups[0]=(CIR1) Groups[1]=CIR1
Index=18 Value=(POS1__X) Groups[0]=(POS1__X) Groups[1]=POS1__X
Index=30 Value=(POS1__Y) Groups[0]=(POS1__Y) Groups[1]=POS1__Y
Index=42 Value=(POS1__Z) Groups[0]=(POS1__Z) Groups[1]=POS1__Z
Index=54 Value=(POS1__D) Groups[0]=(POS1__D) Groups[1]=POS1__D
源代码如下所示。
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace RegexDemo
{
class Program
{
static void Main(string[] args)
{
var content = "OUTPUT/FA(CIR1),TA(POS1__X),TA(POS1__Y),TA(POS1__Z),TA(POS1__D)";
Console.WriteLine("------------ Original String ----------");
Console.WriteLine( content);
Regex r = new Regex(@"\((\w+)\)");
Console.WriteLine("\n------------ Regex String ----------");
Console.WriteLine($" {r}");
var matches = r.Matches(content);
Console.WriteLine("\n------------ Matches ----------");
foreach (var m in matches.ToArray())
{
Console.WriteLine($"Index={m.Index, -10} Value={m.Value, -16} Groups[0]={m.Groups[0],-12} Groups[1]={m.Groups[1],-12}");
}
}
}
}