正则表达式的一些有用的表达式
“^\d+
"
/
/
非
负
整
数
(
正
整
数
+
0
)
"
[
0
−
9
]
∗
[
1
−
9
]
[
0
−
9
]
∗
" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*
"//非负整数(正整数+0)"[0−9]∗[1−9][0−9]∗” //正整数
“^((-\d+)|(0+))
"
/
/
非
正
整
数
(
负
整
数
+
0
)
"
−
[
0
−
9
]
∗
[
1
−
9
]
[
0
−
9
]
∗
" //非正整数(负整数 + 0) "^-[0-9]*[1-9][0-9]*
"//非正整数(负整数+0)"−[0−9]∗[1−9][0−9]∗” //负整数
“^-?\d+KaTeX parse error: Undefined control sequence: \d at position 11: " //整数 "^\̲d̲+(\.\d+)?” //非负浮点数(正浮点数 + 0)
“^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))KaTeX parse error: Undefined control sequence: \d at position 16: " //正浮点数 "^((-\̲d̲+(\.\d+)?)|(0+(…” //非正浮点数(负浮点数 + 0)
“^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))KaTeX parse error: Undefined control sequence: \d at position 16: " //负浮点数 "^(-?\̲d̲+)(\.\d+)?” //浮点数
“1+
"
/
/
由
26
个
英
文
字
母
组
成
的
字
符
串
"
[
A
−
Z
]
+
" //由 26 个英文字母组成的字符串 "^[A-Z]+
"//由26个英文字母组成的字符串"[A−Z]+” //由 26 个英文字母的大写组成的字符串
“2+
"
/
/
由
26
个
英
文
字
母
的
小
写
组
成
的
字
符
串
"
[
A
−
Z
a
−
z
0
−
9
]
+
" //由 26 个英文字母的小写组成的字符串 "^[A-Za-z0-9]+
"//由26个英文字母的小写组成的字符串"[A−Za−z0−9]+” //由数字和 26 个英文字母组成的字符串
“^\w+KaTeX parse error: Undefined control sequence: \w at position 33: …者下划线组成的字符串 "^[\̲w̲-]+(\.[\w-]+)*@…” //email 地址
“3+://(\w+(-\w+))(.(\w+(-\w+)))(?\S)?
"
/
/
u
r
l
/
(
d
2
∣
d
4
)
−
(
(
0
(
[
1
−
9
]
1
)
)
∣
(
1
[
1
∣
2
]
)
)
−
(
(
[
0
−
2
]
(
[
1
−
9
]
1
)
)
∣
(
3
[
0
∣
1
]
)
)
" //url /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))
"//url/(d2∣d4)−((0([1−9]1))∣(1[1∣2]))−(([0−2]([1−9]1))∣(3[0∣1]))/ // 年-月-日/^((0([1-9]{1}))|(1[1|2]))/((0-2)|(3[0|1]))/(d{2}|d{4})
/
/
/
月
/
日
/
年
"
(
[
w
−
.
]
+
)
@
(
(
[
[
0
−
9
]
1
,
3
.
[
0
−
9
]
1
,
3
.
[
0
−
9
]
1
,
3
.
)
∣
(
(
[
w
−
]
+
.
)
+
)
)
(
[
a
−
z
A
−
Z
]
2
,
4
∣
[
0
−
9
]
1
,
3
)
(
]
?
)
/ // 月/日/年 "^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)
///月/日/年"([w−.]+)@(([[0−9]1,3.[0−9]1,3.[0−9]1,3.)∣(([w−]+.)+))([a−zA−Z]2,4∣[0−9]1,3)(]?)” //
Emil
“(d±)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?” //电话号码
“^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}
|1dd|2[0-4]d|25[0-5])KaTeX parse error: Undefined control sequence: \d at position 63: …(((1[6-9]|[2-9]\̲d̲)\d{2})-(0?[135…
C#正则表达式
图片 src[>]*[/].(?:jpg|bmp|gif)(?:”|’)
中文 ^([\u4e00-\u9fa5]+|[a-zA-Z0-9]+)$
网址 "<a.+?href=’""(?!mailto:)(?>foundAnchor>[’"">]+?)[>]?>"
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空行的正则表达式:\n[\s| ]\r
匹配 HTML 标记的正则表达式:/<(.)>.</\1>|<(.) />/
匹配首尾空格的正则表达式:(^\s)|(\s*$)(像 vbscript 那样的 trim 函数)
匹配 Email 地址的正则表达式:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
匹配网址 URL 的正则表达式:http://([\w-]+.)+[\w-]+(/[\w- ./?%&=]*)?
以下是例子:
利用正则表达式限制网页表单里的文本框输入内容:
用 正 则 表 达 式 限 制 只 能 输 入 中 文 :
οnkeyup=“value=value.replace(/[^\u4E00-\u9FA5]/g,’’)” onbeforepaste=“clipboardData.setData(’
text’,clipboardData.getData(‘text’).replace(/[^\u4E00-\u9FA5]/g,’’))”
1.用正则表达式限制只能输入全角字符:οnkeyup=“value=value.replace(/[^\uFF00-\uFFFF]/g,’’)” onbeforepaste=“clipboardData.setD
ata(‘text’,clipboardData.getData(‘text’).replace(/[^\uFF00-\uFFFF]/g,’’))”
2.用正则表达式限制只能输入数字 :
οnkeyup="value=value.replace(/[^\d]/g,’’)
"onbeforepaste=“clipboardData.setData(‘text’,clipboar
dData.getData(‘text’).replace(/[^\d]/g,’’))”
3. 用 正 则 表 达 式 限 制 只 能 输 入 数 字 和 英 文 :
οnkeyup="value=value.replace(/[\W]/g,’’) "onbeforepaste=“clipboardData.setData(‘text’,clipboar
dData.getData(‘text’).replace(/[^\d]/g,’’))”
4.计算字符串的长度(一个双字节字符长度计 2,ASCII 字符计 1)
String.prototype.len=function(){return this.replace([^\x00-\xff]/g,“aa”).length;}
5.javascript 中没有像 vbscript 那样的 trim 函数,我们就可以利用这个表达式来实现,如下:
String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, “”);
}
利用正则表达式分解和转换 IP 地址:6.下面是利用正则表达式匹配 IP 地址,并将 IP 地址转换成对应数值的 Javascript 程序:
function IP2V(ip)
{
re=/(\d+).(\d+).(\d+).(\d+)/g //匹配 IP 地址的正则表达式
if(re.test(ip))
{
return RegExp.$1Math.pow(255,3))+RegExp.$2Math.pow(255,2))+RegExp.$3*255+RegExp.
KaTeX parse error: Expected 'EOF', got '}' at position 6: 4*1 }̲ else { throw …“, “$1”);
这个语句返回字符串 abra,其前导和后缀的空格都去掉了。
上面的模式对于删除任意字符串中的前导和后续空格都非常有用。在 C#中,我们还经
常使用字母字符串,在一个字母字符串中,编译程序不把字符“ \” 作为转义字符处理。在
使用字符“\”指定转义字符时,@”…“是非常有用的。另外值得一提的是$1 在字符串替换方
面的使用,它表明替换字符串只能包含被替换的字符串。
匹配引擎的细节
现在,我们通过一个组结构来理解一个稍微复杂的例子。看下面的例子:string text = “abracadabra1abracadabra2abracadabra3”;
string pat = @”
( # 第一个组的开始
abra # 匹配字符串 abra
( # 第二个组的开始
cad # 匹配字符串 cad
)? # 第二个组结束(可选)
) #
第一个组结束
匹配一次或多次
“;
//利用 x 修饰符忽略注释
Regex r = new Regex(pat, “x”);
//获得组号码的清单
int[] gnums = r.GetGroupNumbers();
//首次匹配
Match m = r.Match(text);
while (m.Success)
{
//从组 1 开始
for (int i = 1; i < gnums.Length; i++)
{
Group g = m.Group(gnums[i]);
//获得这次匹配的组Console.WriteLine(“Group”+gnums[i]+”=["+g.ToString()+"]");
//计算这个组的起始位置和长度
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
Console.WriteLine(" Capture" + j + “=[”+c.ToString()
- “] Index=” + c.Index + " Length=" + c.Length);
}
}
//下一个匹配
m = m.NextMatch();
}
这个例子的输出如下所示:
Group1=[abra]
Capture0=[abracad] Index=0 Length=7
Capture1=[abra] Index=7 Length=4
Group2=[cad]
Capture0=[cad] Index=4 Length=3
Group1=[abra]
Capture0=[abracad] Index=12 Length=7
Capture1=[abra] Index=19 Length=4
Group2=[cad]Capture0=[cad] Index=16 Length=3
Group1=[abra]
Capture0=[abracad] Index=24 Length=7
Capture1=[abra] Index=31 Length=4
Group2=[cad]
Capture0=[cad] Index=28 Length=3
我们首先从考查字符串 pat 开始,pat 中包含有表达式。第一个 capture 是从第一个圆
括号开始的,然后表达式将匹配到一个 abra。第二个 capture 组从第二个圆括号开始,但第
一个 capture 组还没有结束,这意味着第一个组匹配的结果是 abracad ,而第二个组的匹配
结果仅仅是 cad。因此如果通过使用?符号而使 cad 成为一项可选的匹配,匹配的结果就
可能是 abra 或 abracad。然后,第一个组就会结束,通过指定+符号要求表达式进行多次匹
配。
现在我们来看看匹配过程中发生的情况。首先,通过调用 Regex 的 constructor 方法建
立表达式的一个实例,并在其中指定各种选项。在这个例子中,由于在表达式中有注释,
因此选用了 x 选项,另外还使用了一些空格。打开 x 选项,表达式将会忽略注释和其中没
有转义的空格。
然后,取得表达式中定义的组的编号的清单。你当然可以显性地使用这些编号,在这
里使用的是编程的方法。如果使用了命名的组,作为一种建立快速索引的途径这种方法也
十分有效。
接下来是完成第一次匹配。通过一个循环测试当前的匹配是否成功,接下来是从 group
1 开始重复对组清单执行这一操作。在这个例子中没有使用 group 0 的原因是 group 0 是一
个完全匹配的字符串,如果要通过收集全部匹配的字符串作为一个单一的字符串,就会用
到 group 0 了。
我们跟踪每个 group 中的 CaptureCollection。通常情况下每次匹配、每个 group 中只能
有一个 capture,但本例中的 Group1 则有两个 capture:Capture0 和 Capture1。如果你仅需
要 Group1 的 ToString,就会只得到 abra,当然它也会与 abracad 匹配。组中 ToString 的值
就是其 CaptureCollection 中最后一个 Capture 的值,这正是我们所需要的。如果你希望整
个过程在匹配 abra 后结束,就应该从表达式中删除+符号,让 regex 引擎知道我们只需要
对表达式进行匹配。
基于过程和基于表达式方法的比较
一般情况下,使用规则表达式的用户可以分为以下二大类:第一类用户尽量不使用规
则表达式,而是使用过程来执行一些需要重复的操作;第二类用户则充分利用规则表达式
处理引擎的功能和威力,而尽可能少地使用过程。
对于我们大多数用户而言,最好的方案莫过于二者兼而用之了。我希望这篇文章能够说明.NET 语言中 regexp 类的作用以及它在性能和复杂性之间的优、劣点。
基于过程的模式
我们在编程中经常需要用到的一个功能是对字符串中的一部分进行匹配或其他一些
对字符串处理,下面是一个对字符串中的单词进行匹配的例子:
string text = “the quick red fox jumped over the lazy brown dog.”;
System.Console.WriteLine(“text=[” + text + “]”);
string result = “”;
string pattern = @"\w+|\W+";
foreach (Match m in Regex.Matches(text, pattern))
{
// 取得匹配的字符串
string x = m.ToString();
// 如果第一个字符是小写
if (char.IsLower(x[0]))
//
变成大写
x = char.ToUpper(x[0]) + x.Substring(1, x.Length-1);
//
收集所有的字符
result += x;
}
System.Console.WriteLine(“result=[” + result + “]”);
正象上面的例子所示,我们使用了 C#语言中的 foreach 语句处理每个匹配的字符,并
完成相应的处理,在这个例子中,新创建了一个 result 字符串。这个例子的输出所下所示:
text=[the quick red fox jumped over the lazy brown dog.]
result=[The Quick Red Fox Jumped Over The Lazy Brown Dog.]
基于表达式的模式
完成上例中的功能的另一条途径是通过一个 MatchEvaluator,新的代码如下所示:static string CapText(Match m)
{
//取得匹配的字符串
string x = m.ToString();
//
如果第一个字符是小写
if (char.IsLower(x[0]))
//
转换为大写
return char.ToUpper(x[0]) + x.Substring(1, x.Length-1);
return x;
}
static void Main()
{
string text = “the quick red fox jumped over the
lazy brown dog.”;
System.Console.WriteLine(“text=[” + text + “]”);
string pattern = @"\w+";
string result = Regex.Replace(text, pattern,
new MatchEvaluator(Test.CapText));
System.Console.WriteLine(“result=[” + result + “]”);
}
同时需要注意的是,由于仅仅需要对单词进行修改而无需对非单词进行修改,这个模
式显得非常简单。
常用表达式为了能够更好地理解如何在 C#环境中使用规则表达式,我写出一些对你来说可能有用
的规则表达式,这些表达式在其他的环境中都被使用过,希望能够对你有所帮助。
罗马数字
string p1 = “^m*(d?c{0,3}|c[dm])” + “(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$”;
string t1 = “vii”;
Match m1 = Regex.Match(t1, p1);
交换前二个单词
string t2 = “the quick brown fox”;
string p2 = @"(\S+)(\s+)(\S+)";
Regex x2 = new Regex(p2);
string r2 = x2.Replace(t2, “$3$2KaTeX parse error: Undefined control sequence: \w at position 58: …string p3 = @"(\̲w̲+)\s*=\s*(.*)\s…”;
Match m3 = Regex.Match(t3, p3);
实现每行 80 个字符
string t4 = “********************” - “******************************”
- “******************************”;
string p4 = “.{80,}”;
Match m4 = Regex.Match(t4, p4);
月/日/年 小时:分:秒的时间格式
string t5 = “01/01/01 16:10:01”;
string p5 = @"(\d+)/(\d+)/(\d+) (\d+)😦\d+)😦\d+)";
Match m5 = Regex.Match(t5, p5);
改变目录(仅适用于 Windows 平台)
string t6 = @“C:\Documents and Settings\user1\Desktop”;string r6 = Regex.Replace(t6,@"\user1\", @"\us