正则表达式使用示例详解

前言

在这里,我们将尝试去学习一下 .net core EF Core 中调用存储过程。

我们知道,EF Core 是不支持直接调用存储过程的,那它又提供了什么样的方式去执行存储过程呢?有如下方法:

1、FromSql,官方文档

?

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

下面通过实例代码介绍下正则表达式使用

//一个数据类型,记录文本规则,一些事先定义好的一些特殊字符,对字符串的过滤逻辑

//表单验证账号长度,字母或数字组合,高级搜索

//特点,不仅js有;极简的方式操作字符串;灵活,功能强大

// 正则表达式大全

?

1

2

var patt1=new RegExp("e");

document.write(patt1.test("The best things in life are free"));

/*是否带有小数*/

?

1

2

3

4

function isDecimal(strValue ) {

var objRegExp= /^\d+\.\d+$/;

return objRegExp.test(strValue);

}

/*校验是否中文名称组成 */

?

1

2

3

4

function ischina(str) {

var reg=/^[\u4E00-\u9FA5]{2,4}$/; /*定义验证表达式*/

return reg.test(str); /*进行验证*/

}

/*校验是否全由8位数字组成 */

?

1

2

3

4

5

6

function isStudentNo(str) {

var reg=/^[0-9]{8}$/; /*定义验证表达式*/

return reg.test(str); /*进行验证*/

}

var arr = new Array();

var reg = new RegExp(/\d/);

//表示匹配数字

?

1

2

reg = reg.test("jndwjdw");

console.log(reg);

//正则对象。test(需要验证的字符串)

//字面量声明

var reg2 = /男|女/;

//有没有其中一个

?

1

2

3

var reg = reg2.test("呦呦哟偶女");

console.log(reg);

console.log(/男|女/.test("哈迪哈迪哈女"));

//语法

//.test();正则表达式检测某段字符串

//预定义类

?

1

2

3

4

5

6

7

console.log(/./.test("\r")); //除了回车和换行外的任意字符

console.log(/\d/.test("123")); //检测是不是数字

console.log(/\D/.test("sh")); //非数字字符,只要不是数字就true,只要有一个就是true

console.log(/\s/.test("\r")); //只要有不可见就true\r\n\f\h\两个空字符串拼接是false

console.log(/\S/.test("ah7")); //只要有可见字符就对

console.log(/\w/.test("b-8")); //所有字母数字和下短线_,只要有就是对短线

console.log(/\W/.test(("bg8-@"))); //true//只要有非单词字符就是对

//自定义类,没有\

?

1

2

3

4

5

6

console.log(/d/.test("123")); //检测这段里面有不有d这个字 //

console.log(/yskma/.test("yskmama")); //true//检测这段字符串包不包含yskma,不能断开不能中间穿插别的

console.log(/yskmama/.test("ysk")); //false //或和优先级

console.log(/ysk|mama/.test("ysk")); //true

console.log(/ys(k|m)a/.test("ysk")); //false//检测这段字符串中有不有yska或者ysma

console.log(/ys(k|m)a/.test("yskma")); //false//检测这段字符串中有不有yska或者ysma

//简单类[]代表一个字符

?

1

2

3

console.log(/[abc]/.test("gbhigf")); //true//只要出现abc中 的任意一个就是对

console.log(/y[abc]z/.test("yaz")); //true//包含yz,并选一个a

console.log(/y[abc]z/.test("yabcz")); //false//abc只能要一个

//负向类[^ ]取反

?

1

2

console.log(/[^abc]/.test("a")); //false//除了括号外的内容才是对,有就是错,不能有括号内的

console.log(/[^abc]/.test("af")); //true//除了括号外的内容才是对,有就是错,不能有括号内的

//范围类

console.log(/[0-9]/.test("b8jg")); //true

//组合类,组合起来就是组合类,自定义类

//^边界,以。。开头

//$以。。结尾

//^bc$严格匹配

//.回车和换行以外的

?

1

2

3

4

5

6

7

console.log(/^6a/.test("6akjjkak")); //true

console.log(/^6.a/.test("6akjjkak")); //false

console.log(/[.]{8}/.test("6akjjkak")); //false,当前"."就是代表字符串".",此处没有8个".",所以false;

console.log(/ac$/.test("6akjjkakac")); //true//ac结尾

console.log(/^6a$/.test("6a")); //true

console.log(/^\d$/.test("9")); //true//只能出现一次

console.log(/^abc\d$/.test("abc7")); //true//只能出现一次

//量词:?0||1次;+前面的>=1次;*>=0次

?

1

2

3

4

5

6

console.log(/^colo*r$/.test("color")); //true

console.log(/^colo+r$/.test("color")); //true

console.log(/^colo?r$/.test("color")); //true

console.log(/^colo?r$/.test("colr")); //true

console.log(/^colo?r$/.test("coloor")); //false

console.log(/^colo*r$/.test("colooooooor")); //true

//量词,{}前面出现的:。。{n}n次;{n,}>=n;{n,m}...>=n..<=m

//*{0,}..?{0,1}....+{1,}

//括号总结{}次数;[]一个;()一组,分组

//转Unicode:escape("你好")-----Ununicod("u%hkkblpp%^Vhk")

//所有汉字在一到与之间

?

1

2

console.log(/[\u4e00-\u9fa5]/.test("哈"));

console.log(/[\u4e00-\u9fa5]{3}/.test("哈你好"));

//字符串替换

?

1

2

3

var str = "abcde";

console.log(str.replace("a", "b")); //bbcde

console.log(str.replace(/a/g, "b")); //bbcde

//换成句号

?

1

2

3

var str = "a,b,c,d,e";

var str2 = str.replace(/,/g, "."); //g是替换全部

console.log(str2);

//修改成绩

?

1

2

3

4

5

6

7

8

9

10

11

12

13

var str = "a,b,c,70,90";

var str2 = str.replace(/\d{1,}/g, "100"); //g是替换全部

console.log(str2); //吧,.都改成。

var str = "a,b,c,70,90.";

var str2 = str.replace(/[ , , .]/g, "。"); //g是替换全部

console.log(str2);

var stra = " abc "

function MyTirm(stra) {

var str3 = stra.replace(/^\s+|\s+$/g, ""); //去掉前后空格空格换成空字符串

return str3;

}

var str2 = MyTirm(stra);

console.log("==" + str2 + "==");

//想要的字符提取出来,提取邮箱 //来不及写

//math,提取符合要求的元素

//分组提取,提取邮箱的每一个部分

RegExp.$1, RegExp.$2, RegExp.$3

//检索字符indexof();lastindexof();返回下标

?

1

2

3

var str = "张三:1000,李四:5000,王五:8000。";

var arr = str.match(/\d+/g);

console.log(arr); //math返回数组,提取元素

//exec只取一个,math可以取全部的

//正则对象:test,exec........字符串:math,spilt,search,

//用某个字符分隔字符串

?

1

2

3

var str = "[email protected],[email protected] [email protected] 2、[email protected] [email protected]...";

var arr = str.match(/\w+@\w+(\.\w+)+/g);

console.log(arr);

//6 分组提取

?

1

2

3

4

5

6

7

8

9

10

//提取email中的每一部分

var str = "[email protected]";

var reg = /(\w+)@(\w+)\.(\w+)(\.\w+)?/;

var array = str.match(reg); //获取分组的数据 ()是分组

console.log(RegExp.$1); //123123

console.log(RegExp.$2); //xx

console.log(RegExp.$3); //com //分组练习

var str = "5=a, 6=b, 7=c";

str = str.replace(/(\d)=(\w)/g, "$2====$1"); //吧567分3组,吧abc分3组,2组在前面,1组在后面

console.log(str);

//i 忽略大小写

//g 全局匹配

//控制字符串相关方法

//1、正则对象的 test exec

//2、字符串的 replace search match split

//用法:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

console.log(/\d/.test("123"));

console.log(/[\u4e00-\u9fa5]{3}/.test("哈你好"));

//除了.test和search方法能直接执行,math,replace,split,exec都需要数组接收返回值

var str = "abc100,ccc200,ddd300";

var arr = /\d+/.exec(str);

console.log(arr + "这儿"); //100//只能匹配一项,可以用在分组匹配

var arr = str.match(/\d+/g);

console.log(arr);

var str = "abc100ccc200ddd300";

var arr = str.split(/\d+/);

console.log(arr);

var str = "哈哈哈哈,100分"; //检索里面数字出现的下标

console.log(str.search(/\d+/));

var str = "abcdebfg";

var strNew = str.replace("b", "d");

console.log(strNew);

console.log(str);

var v = 2

new RegExp("^\\d+" + v + "$").test(12) //true

总结

以上所述是小编给大家介绍的正则表达式使用示例详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

 

2、执行SQl命令

?

1

DbContext.Database.ExecuteSqlCommand()

但是,这两种方式都有局限性:

1、FromSql方式的结果一定要是实体类型,就是数据库表映射的模型。这意味着,执行存储过程返回的结果一定是跟数据库表相关的所有字段;

2、FromSql方式的结果不能有关联关系数据。这就相当于不能 join ,也返回不了 join 的关联表的数据。

3、ExecuteSqlCommand执行插入、更新跟删除的存储过程不能直接映射到实体(EF Core不支持嘛,在讲 EF 跟 EF Core 的区别时已经很清晰了),所以,CUD 方法不能直接调用 SaveChanges 方法。

我们来试试演示一下:

(1)准备一个存储过程,一般为了方便,直接就是 DB-First,执行以下的 SQL 脚本就OK了

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

USE [Library]

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE PROCEDURE [dbo].[proc_getbooks]

   @name nvarchar(50)

  AS

  BEGIN

   SET NOCOUNT ON;

   select * from books where name like @name +'%'

  END

GO

当创建好了这个有传参的有返回结果的存储过程的时候,数据库在可编程性下就有一个存储过程了(这个数据库是我专门用来做demo的)

(2)用 FromSql 调用存储过程,由上面就可以知道它是 DbSet 的方法,而 DbSet 是可以执行原生的 sql 语句去查询底层的数据库。同样,使用 DbSet 可以执行存储过程,从而返回实体类型,但就是具有上面所说的局限性罢了。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

//用 FromSql 调存储过程

   var name = "C";

   var books = _context.Books

      .FromSql($"proc_getbooks {name}")

      .ToList();

   //or 使用 exec 关键字调用存储过程

   //var books = _context.Books.FromSql($"exec proc_getbooks {name}").ToList();

   //or 使用 SqlParameter 实例进行参数的插入

   //var param = new SqlParameter()

   //{

   // ParameterName = "@name",

   // SqlDbType = System.Data.SqlDbType.NVarChar,

   // Direction = System.Data.ParameterDirection.Input,

   // Size = 50,

   // Value = name

   //};

   //or 使用 @p0 代表第一个参数,则 @p1 就代表第二个参数等以此类推

   //var books = _context.Books.FromSql("proc_getbooks @p0", name).ToList();

同样,在这里值得一提的是,当我们多次调用同一个存储过程,传递同样的参数的时候,比如像下面:

?

1

2

3

4

5

6

7

8

//用 FromSql 多次调同一个存储过程

   var name = "C";

   var list1 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

   var list2 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

   var list3 = _context.Books.FromSql($"proc_getbooks {name}").ToList();

所有的实体默认(可以设置)都会被 DbContext 进行跟踪。如果你执行同样的存储过程,传同样的参数的时候,进行多次执行的时候,相当于执行同样的 sql 语句多次,但返回的结果确认一样的, 根据DbContext 的跟踪,直接就获取缓存进行返回结果了。就是说,存储过程会被调用多次,但只查了一次数据库,其他的在缓存里拿数据。

(3)用ExecuteSqlCommand 调用存储过程,这个跟 EF 是一个毛样的,由于要测试的话,还要创建一个存储过程,因为这个执行查询没有意义,如果你看它的返回的话,都是 int 类型,而且返回结果都是影响的行数。

看看源码:

其实 ExecuteSqlCommand 最终是调用 ExecuteNonQuery,就是执行非查询的语句,返回影响的行数,也验证了刚才所说的。

扯远了,那么再创建一个存储过程吧

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

CREATE PROCEDURE [dbo].[proc_createbook]

 @name Varchar(50),

 @author Varchar(50),

 @cateid int

AS

BEGIN

 SET NOCOUNT ON;

 Insert into books(

   [name]

   ,[author]

   ,[createtime]

   ,[isdel]

   ,[cateid]

   )

 Values (@name, @author,GETDATE(),0,@cateid)

END

GO

创建后

来调用以下试试:

?

1

2

3

4

5

//用 ExecuteSqlCommand 调存储过程, 用parameters: new[] {}也是可以的

var name = "C# 高级进阶";

var author = "-";

var cateid = 1;

_context.Database.ExecuteSqlCommand("proc_createbook @p0,@p1,@p2", name, author, cateid);

执行结果:

OK,是可以执行成功的。

到这里先完成第一部分先,接下来就做调用存储过程的扩展,因为单靠这两种调用方式,我们是不会满足的!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对主机吧的支持。

猜你喜欢

转载自blog.csdn.net/zhujibcom/article/details/90045639