1.为什么要用正则表达式
1.1 正则表达式主要操作字符串,可验证是否符合某种规则,可从中截取满足设定要求的子字符串,可对子字符串进行替换
1.2 如果不用正则表达式,为了程序的严谨你的程序必定要有大量的if判断,和IndexOf、SubString之类的代码,并且即使你自认为考虑的很全面,也往往有可能会忽视其中的某一种情况
2.C#正则表达式工具代码类
需要using System.Text.RegularExpressions;
/// <summary>
/// 验证字符串是否满足正则表达式
/// </summary>
/// <param name="regularExpression">正则表达式</param>
/// <param name="inputStr">输入字符串</param>
/// <returns>true为满足;false为不满足</returns>
public static bool RegexIsOK(string regularExpression, string inputStr)
{
Regex objRegex = new Regex(regularExpression, RegexOptions.IgnoreCase);
if (objRegex.IsMatch(inputStr))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 提取符合正则表达式要求的所有字符串
/// </summary>
/// <param name="regularExpression">正则表达式</param>
/// <param name="inputStr">输入字符串</param>
/// <returns>返回的数据集</returns>
public static List<string> RegexExtracts(string regularExpression, string inputStr)
{
List<string> list = new List<string>();
var cols = Regex.Matches(inputStr, regularExpression);
for (int i = 0; i < cols.Count; i++)
{
list.Add(cols[i].Value);
}
return list;
}
/// <summary>
/// 提取符合正则表达式要求的第一个匹配项
/// </summary>
/// <param name="regularExpression">正则表达式</param>
/// <param name="inputStr">输入字符串</param>
/// <returns>返回的数据</returns>
public static string RegexExtractOnlyOne(string regularExpression, string inputStr)
{
return Regex.Match(inputStr, regularExpression).Value;
}
3.举例
例如说我的程序有一个用户书写脚本指令的功能,大致的格式是 xMove(200,33,Abs); 或 xMove(2000,330000,Rel);
这个脚本指令意思是X轴伺服马达以绝对位置(Abs)或相对位置(Rel),目标位置是200或2000,运行速度是33或330000
因为你不知道你的客户会不会是个傻傻的人,所以你一定要考虑的很全面,上述这个例子如果用常规的if加字符串截取的方式做很麻烦
if (Content.StartsWith("xMove") && Content.Contains("(") && Content.Contains("(") && Content.Contains(","))
{
int index1 = Content.IndexOf('(');
int index2 = Content.IndexOf(',');
int index3 = Content.IndexOf(')');
if (index1 < index2 && index2 < index3)
{
if (double.TryParse(Content.Substring(index1, index2 - index1), out pos) && double.TryParse(Content.Substring(index2, index3 - index2), out speed))
{
flag = true;
}
}
}
else
{
Log.Warn($"第{Id}行编译失败:\"{Content}\"指令不符合\"xMove(1000,20000);\"格式");
}
诸如上述代码,要判断括号、分号、逗号的位置,以及三个参数都是可以合理的转换为数字和对应的枚举
/* Content待验证字符串 xMove(200,33,Abs);
* ^xMove\(\d+,\d+,(Abs|rel)\);$ 说明:^xMove表示以xMove开头 ;$表示以;结尾 ()不加\表示一个整体,加了\验证()本身 Abs|Rel是要么是Abs要么是Rel
* \d+|(Abs|Rel) \d表示[0-9] +表示至少重复1次 |表示或的意思
*/
if (RegexTool.RegexIsOK(@"^xMove\(\d+,\d+,(Abs|rel)\);$", Content))
{
List<string> list = RegexTool.RegexExtracts(@"\d+|(Abs|Rel)", Content);
if (list.Count==3)
{
pos = Convert.ToDouble(list[0]);
speed = Convert.ToDouble(list[1]);
moveType = (Enum_RelOrAbs)Enum.Parse(typeof(Enum_RelOrAbs), list[2]);
return true;
}
}
4.比较好的网址推荐和工具
https://c.runoob.com/front-end/854
https://www.runoob.com/w3cnote/regular-expression-30-minutes-tutorial.html
5.对分组(断言)的理解
例如我现有一个字符串: 直线工具.起点X[562]
其中.[]这三个字符的格式是必须具有的
对其格式的验证表达式:^\w+\.\w+\[\w+\]$ \w+ 匹配字母或数字或下划线或汉字至少有一个 \. \[ \]都是转义
提取:\w+(?=\.)|(?<=\.)\w+(?=\[)|(?<=\[)\w+(?=\]) (?=\.) 以.结尾不包括. (?<=\.)\w+(?=\[) 以.开始以[结尾 (?<=\[)\w+(?=\]) 以[开始以]结尾
提取以("开头,以")结尾,且中间必须有.,点前和点后都必须有内容,且范围最小
(?<=\(").+?\..+?(?=\"\))
小结
磨刀不误砍柴工,掌握更好的技术,可以提高自己编写代码的生产力