数往知来C#之 正则表达式 委托 XML<六>

时间:2024-08-16 21:34:26

C# 正则表达式篇

一、正则表达式
正则表达式就是一个字符串,不要想着一下子可以写出一个通用的表达式,先写,不正确再改
写正则表达式就是在找规律
关键字:Regex   
--》引入命名空间  System.Text
常用的方法
1、 匹配:
   --》Regex.IsMatch(要匹配的字符串,正则表达式); 判断指定的正则表达式和指定的字符串是否匹配
如果匹配返回true,否则返回false

Console.WriteLine("请输入邮政编码");
string regex = @"^\d{6}$";
if (Regex.IsMatch(Console.ReadLine(), regex))
{
Console.WriteLine("输入正确");
}
else
{
Console.WriteLine("error");
}

2、 提取: 
  -->Regex.Match(要提取的字符串,正则表达式);

在指定的字符串中提取指定的正则表达式匹配的字符,  Match只提取第一个匹配到的数据。

string regex = @"^(http|ftp)://\w+(\.\w+)+/\w+\.\w+\?\w+=\w+(&\w+=\w+)*";
string IP = "modaorong@qq.com";
string regex = @"\w+@(\w+\.\w+)/.*";
Match m = Regex.Match(IP, regex);
Console.WriteLine(m.Groups[].Value);

--》Regex.Matchs      
   Matchs提取所有需要的数据,

会返回一个MatchCollection集合,没一个匹配上的数据就是这个集合的一个元素

string time = "June    26,     1951";
string regex = @"(\w+)\s*(\d+),\s*(\d+)";
MatchCollection mc = Regex.Matches(time, regex);
foreach (Match m in mc)
{
Console.WriteLine("月{0} 日{1} 年{2}", m.Groups[].Value, m.Groups[].Value, m.Groups[].Value);
}

3、提取组

()在正则表达式里的意思就是优先级和分组的意思,在正则表达式里没遇到一个左圆括号“(”就分一组,

如果没有分组那么整个匹配到的结果就是一组,也就是Groups[0],  Groups[i].Value  就是匹配到的

数据的第i组的值

string day = "2012/05/30";
Console.WriteLine(Regex.Replace(day, @"(\d+)/(\d+)/(\d+)", "$1年$2月$3日"));

提取网页的html代码

--》WebClient类 (导入命名空间  System.net)

string str=实例名.DownloadString(IP地址);      //会返回一个字符串 
提取的结果乱码可以设置encoding属性

实例名.Encoding

贪婪模式与非贪婪模式

取消贪婪模式  +号后面加个?

如果不取消贪婪模式就会尽可能多的匹配,如果一个表达式里出现多个贪婪模式,那么第一个就会尽可能多的匹配,

后面的全都会默认的变成非贪婪,当第一个标记为非贪婪模式那么第二个就会贪婪后面的非贪婪

string path = @"C:\154\2FDF\3FF\4dfgf\5dgdgd\6gd\7dgd\8dgg\9dg\0.txt";
string regex = @"(.+)\\(.+)\\(.+)\\(\w+\.\w+)";//第一个.+是贪婪模式,所以会从尽可能多的匹配,所以第一个.+会一直匹配到7dgd\这里,而第二个第三个.+此时就默认为非贪婪模式,
Match mc= Regex.Match(path, regex); //第二个会匹配8dgg,第三个匹配9dg
Console.WriteLine("{0}\r\n{1}\r\n{2}",mc.Groups [].Value ,mc.Groups [].Value ,mc.Groups [].Value );
Console.ReadKey();

扩展: 反斜线(*****)
在C#中  \表示转义,   \\表示一个斜线(在文本中)   \\\\表示正则表达式中的一个斜线

在正则表达式中    \ 表示转义   \\表示一个斜线(正则表达式中)

C# 委托篇

四、委托

为什么要有委托

--》实现回调  (就是把方法注册给委托变量,然后传出去,然后再外面调用执行这个方法的时候会调回原来的地方执行这个方法)

--》实现多线程

--》自定义执行

委托与指针的区别

--》委托是一个类型,使用的时候,是在使用委托变量,委托是类型安全的,委托的本质就是类。

--》指针式非安全代码,是面向过程的,是地址的一个指向

关键字:delegate

-->delegate void 委托类型名();

访问修饰符只有两个:public/priveta    
委托是类型安全的

delegate bool DelegateMFunc(int i);
delegate void DelegateFunc();
class Person
{
public void Func()
{
Console.WriteLine("哈哈");
}
}
class Program
{
static void Main(string[] args)
{
//Person p = new Person();
//DelegateFunc DFunc;
//DFunc = p.Func;
//DFunc();
DelegateMFunc MyFuncs;
MyFuncs = MyFunc;
bool b= MyFuncs();
Console.WriteLine(b);
Console.ReadKey();
}
static bool MyFunc(int num)
{
Console.WriteLine("我的Func");
return num % == ? true : false;
}
}

用委托实现方法回调的一个简单的案例

namespace _09委托_方法回调
{
Form1
//声明一个委托
public delegate void DFunc();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DFunc NewFunc;//定义一个委托变量
private void button1_Click(object sender, EventArgs e)
{
//给委托变量注册
NewFunc = MyFunc;
Form2 form2 = new Form2(NewFunc);//new一个Form2窗体,在构造方法中把委托变量传过去
form2.Show();//弹窗
}
//这个方法是给委托变量注册的
private void MyFunc()
{
textBox1.Text = "Hello";
}
}
}

//Form2

namespace _09委托_方法回调
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
DFunc MyDele;//定义一个委托变量
//写一个构造函数的重载,有一个参数 用来接收Form1传过来的委托变量
public Form2(DFunc c)
{
this.MyDele = c;//把Form1传过来的委托变量赋给上面定义好的委托变量
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MyDele();//这里使用委托变量实现了回调Form1的函数
}
}
}

C#  委托篇(三连击事件)

写事件必须要有委托

namespace _13三连击事件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
myButton1.MyClik += new threeButtonDelegate(MyShow);
}
void myButton1_MyClik()
{
throw new NotImplementedException();
}
private void MyShow()
{
MessageBox.Show("哈哈,我又变帅了!");
}
}
}
public delegate void threeButtonDelegate();
class MyButton:Button
{
public event threeButtonDelegate MyClik;
int i = ;
protected override void OnClick(EventArgs e)
{
i++;
if (i==)
{
if (MyClik !=null)
{
MyClik();
}
i=;
}
}
}

C# XML篇

五、XML
XML就相当于一个小型的数据库,只不过是以txt来保存

-》大小写敏感

-》只可以有一对根节点

-》标签必须成对出现,

-》标签有开始必须有结束,如果只有一个标签,也要有<test/>结束

-》属性赋值时要用引号引起来

写入
//添加一个根节点
XElement xeRoot = new XElement("Root");
for (int i = ; i < ; i++)
{ //new一个子节点,在构造方法里面给节点命名
XElement xePerson = new XElement("Person");
//用Add方法添加,参数是要添加到哪个根节点就传哪个根节点的对象
xeRoot.Add(xePerson);
XElement xeName = new XElement("Name");
xePerson.Add(xeName);
XElement xeAge = new XElement("Age");
xePerson.Add(xeAge);
XElement xeSex = new XElement("Sex");
xePerson.Add(xeSex);
xePerson.SetAttributeValue("id", i);
//通过Value给节点赋值
xeName.Value = "张三" + i;
xeAge.Value = "";
xeSex.Value = "男";
}
xeRoot.Save("E:\\students.xml"); //保存
读取
//Loed方法获得XML文档,参数是要获得XML文档的路径
XDocument xDoc= XDocument.Load(@"E:\students.xml");
XElement xeRoot =xDoc.Root;//获得这个XML文档的根节点名,
DiGui(xeRoot);//递归调用,把根接待你名传过去
Console.ReadKey();
}
static void DiGui(XElement xe)
{ //循环根节点,
foreach (XElement item in xe.Elements())
{
//判断是否是最后一层子元素
if (!item.HasElements)
{ //得到最后一层节点的名称和里面的值
Console.WriteLine(item.Name +" "+item.Value );
}
foreach (XAttribute xa in item.Attributes())
{
Console.WriteLine("属性:{0} 值:{1}", xa.Name, xa.Value);
}
//递归调用,如果这个节点下面还有节点就再继续循环,知道最后一个节点为止
DiGui(item);
}
}