精华内容
下载资源
问答
  • C语言while循环语句 do while语句 for循环语句

    万次阅读 多人点赞 2019-06-10 14:17:53
    for语句和while语句一样,它的思想是在做循环之前,也是先有一个初值表达式1,然后判断条件表达式2是否成立,如果成立就执行{}里的语句然后跳转到表达式3,表达式3再跳转到表达式2,再次判断表达式2,如若成立再次,...

    一、循环结构的思想及意义:
    知道了循环结构,那么在生活中也一样,我们每天都在重复做着相同的事情,例如:吸气呼气的过程;又如夏天开电扇,电扇一圈一圈的转,这都是在重复。现在大家玩个游戏,一个人A来说一个人B来做,一个人A说命令“敬礼,礼毕”,另一人B做动作十遍;第一种思维那就是说一下命令就让B执行动作,B执行完动作后,A再继续说命令,B再继续做动作,同样的事情重复十遍。如果利用所学的知识,让你输出十遍“敬礼,礼毕”,你会怎么写程序呢?

    /* 输出敬礼礼毕十遍 */
    #include "stdio.h"
    void main()
    {
        printf("1.敬礼、礼毕\n");
        printf("2.敬礼、礼毕\n");
        printf("3.敬礼、礼毕\n");
        printf("4.敬礼、礼毕\n");
        printf("5.敬礼、礼毕\n");
        printf("6.敬礼、礼毕\n");
        printf("7.敬礼、礼毕\n");
        printf("8.敬礼、礼毕\n");
        printf("9.敬礼、礼毕\n");
        printf("10.敬礼、礼毕\n");    
    }
    

    那A要让B说一万遍呢,显然如果还是用上面的程序来写的话,那么今天你一个小时不用做别的了,你就在这里慢慢复制粘贴吧!所以肯定有好的办法:A应该对B说执行命令动作“敬礼、礼毕”十遍。同样的问题大家来看第二段程序代码:

    /* 输出敬礼礼毕十遍 */
    #include "stdio.h"
    void main()
    {
    	int i;
    	i=1;
        while(i<=10)
    	{
    printf("%d.敬礼、礼毕\n",i);
    i=i+1;
    	}   
    }
    

    二、while的基本格式
    while的基本格式:(流程图如右图所示)
    while(表达式)
    {
    语句1;
    ……
    语句 n;
    }
    其中表达式代表了循环条件,整个复合语句为循环体。
    while语句规范:
    1:{和}自成一行
    2:语句1—语句n自动缩进
    while循环属于当型循环,也就是先判断表达式的值是否为真的(也可以理解为条件是否成立),若为真则循环,否则退出循环。
    它的格式变形如下;
    表达式1;
    while(表达式2)
    {
    语句;
    表达式3;
    }
    其中表达式1代表了程序循环前的初始值,表达式2代表了控制条件,表达式3代表了增量变化
    拿输出1到100为例分析。
    最初始的值(假设变量为i)应该是i=1;条件是i<101(或i<=100);语句是输出相应的变量值 printf(“%d ”,i);而表达式3应该是输出一个后进入下一个数,也就是i++;
    所以它的代码也就很容易就出来了:

    void main()
    {
        int i;
        i=1;
        while(i<101)
    {
      printf(“%d ”,i);
      i++;   
    }
    }
    

    do—while循环语句
    do–while语句
    在循环中有当型循环,还有直到型循环。接下来我们就来学习下直到型循环。
    一、do—while语句格式
    1.do—while语句格式1
    表达式1;
    do
    {
    语句;
    表达式3;
    } while(表达式2);
    其中表达式1代表了程序循环前的初始值,表达式2代表了控制条件,表达式3代表了增量变化
    这种格式在程序中已经很少用了。主要应用于下种变形格式:
    2.do—while语句格式变形
    do
    {
    语句;
    } while(条件表达式);
    二、do-while语句的思想及意义
    do英文翻译成中文是做的意思,那么从上面的结构我们也能看出,do语句后判断条件表达式,如果条件还表达式成立,再次执行语句,直到条件表达式不成立,往下继续执行。所以do—while的中心思想是至少执行一次循环语句。
    三、do-while循环结构实例
    下面我们一些操作实例来讲解循环结构的逻辑思维过程。
    1.求1+2+3+4±—+100和是多少?
    (1)步骤1,首先我们应该分析的是,我们要求一个数即和,那么和初值是几呢? sum=0
    (2)sum+=1;
    (3)sum+=2;
    (4)sum+=3;
    (5)假如我们如一个变量i来代表值的变化的话那么我们应该也能推算去,求和其实就是
    (6)sum+=i;只是i要从1变化到100
    (7)while代码参考代码如下

    /*求1+2+3+---+100的和*/
    #include "stdio.h"
    void main()//求各
    {
    	//定义变量并初始化
    	int i=1;
    	int sum=0;
    	while(i<=100)  //条件表达式
    	{
    		sum+=i;
    		i+=1; //步长
    	}	
    	printf("和是%d",sum);
    }
    

    (8)do–while代码参考代码如下

    /*求1+2+3+---+100的和*/
    #include "stdio.h"
    void main()//求各
    {
    	//定义变量并初始化
    	int i=1;
    	int sum=0;
    	do
    	{
    		sum+=i;
    		i+=1; //步长
    	}	while(i<=100); //条件表达式
    	printf("和是%d",sum);
    }
    

    2.输入qq的密码;输入正确则显示登录成功,否则可以一直输入密码直到对为至,假设密码为123456
    (1)那么我们分析题目,应该是先输入后判断的一种循环方式,那么应该选择do—while语句
    (2)程序中要求我们输入密码,密码可以变,所以要给密码定义成一个变量,我们假设int password;
    (3)因为密码是输入的,所以没有初始值
    (4)输入密码以后我们应该判断密码是否和默认密码相同
    (5)相同则登录成功
    (6)不相同则重新
    (7)do–while代码参考代码如下

    /*判断qq密码*/
    #include "stdio.h"
    void main()//登录
    {
    	//定义变量并初始化
    	int password;
        do	
    	{
    		printf("请输入qq登录密码:");
    		scanf("%d",&password);
    	}while(password!=123456);  	//条件表达式
    	printf("登录成功");
    }
    

    (8)do—while语句是可以被while()替换,其实循环之间的语句都可以相互替换,哪种方法更适合你,就选那种,也就是说一定要有一种是自己专长的。

    (9)参考代码如下
    /*登录*/
    #include "stdio.h"
    #include "stdlib.h"
    void main()//登录
    {
    	//定义变量并初始化
    	int password;
        while(1)
    	{
    		printf("请输入qq登录密码:");
    		scanf("%d",&password);
    		if(password==123456)
    		{
    			printf("登录成功");
    			break;
    			}
    	}
    	
    }
    

    3.while 与do—while的相同与不同总结?
    (1)while 语句是先计算表达式的值,再执行循环体,do…while是执行完一次循环体,再计算表达式的值
    (2)当表达式的值第一次为假时,while的循环体一次都不执行,do…while则执行一次循环体;
    (3)当表达式的值为真时,两者无区别
    (4)在不确定条件次数的情况下,程序一般用while比较多

    for循环语句
    for 循环为当型循环。for循环最容易实现计数控制循环方法。for循环的使用最为灵活,且适合应用在循环次数确定的情况下。
    for循环的思想是,先分析清楚循环的初始值,循环的控制条件,循环变量的步长变化,然后直接把语句再写到for的循环体里即可,这样可以让问题想的很清楚,流程也很清楚。
    二、for循环语句的应用
    for语句是c语言所提供的功能更强,使用更广泛的一种循环语句。
    1.for语句的一般格式
    (1)第1种情况
    for(表达式1;表达式2;表达式3)
    语句;
    (2)第2种情况
    for(表达式1;表达式2;表达式3)
    {
    语句块;
    }
    2.for语句的注意事项
    (1)各表达式之间分号不能省略
    (2)表达式1与表达式2与表达式3均可省略,一般是不省略的。
    ①当表达式1省略时,相当于省去了为循环变量赋初值,此时应在for语句之前给循环变量赋初值
    ②当表达式2省略时,表示不判断循环条件,也就是认为表达式2始终为真, 这时应在循环体内设法结束循环,否则将成为死循环
    ③当表达式3省略时,即省去修改循环变量的值,但此时应在循环体内设法结束循环
    (3)虽然说表达式可以省略,但是在使用for时,还是要正常使用的,也就是该有的都有。
    三、for的逻辑思维过程
    for语句和while语句一样,它的思想是在做循环之前,也是先有一个初值表达式1,然后判断条件表达式2是否成立,如果成立就执行{}里的语句然后跳转到表达式3,表达式3再跳转到表达式2,再次判断表达式2,如若成立再次,执行{}里的语句语句然后跳转到表达式3,表达式3再跳转到表达式2,如果成立就再重复执行,如果不成立就退出循环。
    for的流程图走向和while语句一模一样,但是for的思维过程,可以直接先分析从第一次开始执行,执行条件是什么,步长是多少,然后执行的语句是什么,套用for的结构即可。

    展开全文
  • Shell语法—— while 条件语句

    千次阅读 2018-10-09 23:25:50
    条件表达式 > do 指令 done 有关脚本运行的相关用法 命令 说明 sh file.sh & 把 file.sh 脚本放到后台运行(后台运行脚本的常用方法) ctl+c 停止执行当前脚本或任务 ctl+z 暂停执行当前脚本或...
    while 循环语句

    while 循环语句语法格式为:

    while < 条件表达式 >
    do
            指令
    done

    有关脚本运行的相关用法

    命令说明
    sh file.sh &把 file.sh 脚本放到后台运行(后台运行脚本的常用方法)
    ctl+c停止执行当前脚本或任务
    ctl+z暂停执行当前脚本或任务
    bg把当前脚本或任务放到后台执行
    fg把当前脚本或任务放到前台执行。如果是多个脚本,需加编号,如: fg 2
    jobs查看当前执行的脚本或任务
    kill关闭执行的脚本任务

    有关进程管理的 Linux 相关命令

    命令说明
    kill、killall、pkill杀掉进程
    ps查看进程
    pstree显示进程状态树
    top显示进程
    renice改变优先权
    nohup用户退出系统之后继续工作
    pgrep查找匹配条件的进程
    strace跟踪一个进程的系统调用情况
    ltrace跟踪进程调用库函数的情况
    小结

    一. while 循环结构及相关语句综合实践

    1. while 循环的特长是执行守护进程,以及实现我们希望循环持续执行不退出的应用,适合用于频率小于 1min 的循环处理其他的 while 循环几乎都可以被 for 循环及定时任务 crontab 功能代替
    2. case 语句可以用 if 语句来替代,而在系统启动脚本时传入少量固定规则字符串的情况下,多用 case 语句,其他普通判断多用 if 语句
    3. 一句换场景,if 语句、for 语句最常用,其次是 while(守护进程)、case(服务启动脚本)

    二. shell 脚本中各个语句的使用场景

    1. 条件表达式,用于简短的条件判断及输出(文件是否存在,字符串是否为空等)
    2. if 取值判断,多用于不同值数量较少的情况
    3. for 最常用于正常的循环处理中

    案例一:
    猜数字
    随机生成一个 100 以内的数字,让用户输入数字来猜。游戏规则:输入的必须是数字,猜错时出现大小提示,才对时给出所用次数

    #!/bin/bash
    total=0
    RETVAL=0
    key=$((RANDOM%100))
    echo "Let's play the guessing game!"
    echo "key:$key"
    panduan(){
            read -p "input num: " num
            expr $num + 1 &>/dev/null
            RETVAL=$?
            if [ $RETVAL -ne 0 ];then
                    echo "number number !!!"
                    panduan
            fi
    }
    
    guess(){
            ((total++))
            if [ $num -lt $key ];then
                    echo "It is too small"
                    panduan
            elif [ $num -gt $key ];then
                    echo "It is too big"
                    panduan
            else
                    echo "Guess right"
                    echo "yi gong cai le $total ci"
                    exit 0
            fi
    }
    main(){
            panduan
            while true
            do
              guess
            done
    }
    main $*

    案例二:
    手机充值并发送短信。这个案例并没有实际用途,可以当做一个综合练习玩玩的
    以下功能:

    1. 充值,但重复充值金额不累计,充值后立即查询余额无法正常使用
    2. 发送短信,输入发送的条数和短信内容,当金额不足时,可以选择(y:充值,n:修改发送条数,o:返回菜单)
    3. 查询余额,只有当使用发送功能选择(o:返回菜单)时,查询才可以生常使用
    4. 退出,结束当前脚本
    #!/bin/bash
    RETVAL=0
    balance=0
    menu(){
    cat << EOF
     1) Recharge
     2) Send information
     3) Query
     4) exit
    EOF
    read -p " please enter a number: " num
    case $num in
            1)
              echo "Welcome to chongzhi !"
              recharge
              ;;
            2)
              echo "Welcome Check the balance !"
              send
              ;;
            3)
              echo "Welcome to the query interface !"
              selects
              ;;
            4)
              echo "Looking forward to your next arrival !"
              exit
              ;;
            *)
              echo "Tips:{1|2|3|4}"
              menu
    esac
    }
    
    recharge(){
            read -p "please enter to RMB: " rmb
            expr $rmb + 1 &>/dev/null
            RETVAL=$?
            if [ $RETVAL -ne 0 ];then
                    echo "please input num"
                    recharge
            fi
            echo "$rmbs  Rechargs success"
            ((rmbs=$rmb + $balance))
            menu
    }
    
    send(){
            while true
            read -p "send several messages: " strips
            expr $strips + 1 &>/dev/null
            RETVAL=$?
            if [ $RETVAL -ne 0 ];then
                    echo "please input num"
                    send
            fi
            ((count=$strips * 15))
            do
              if [ $count -gt $rmbs ];then
                    echo "Insufficient amount !!!"
                    read -p "Recharge(y|n|o) ?" or
                    if [ $or = y -o $or = Y ];then
                            recharge
    
                    elif [ $or = n -o $or = N ];then
                            send
                    else 
                            menu
                    fi
              else 
                    read -p "Please input information content: " input
                    echo "sending:$input  send success"
                    ((balance=$rmbs - $count))
                    echo "Balance: $balance"
              fi
              ((rmbs=$rmbs - $count))
            done
    }
    
    selects(){
            echo "Query:$balance"
            menu
    }
    
    menu $*

    案例三:
    使用 while 守护进程的方式监控网站,每隔 10s 检测一次网站是否正常

    #!/bin/bash
    . /etc/init.d/functions
    count=0
    url_list=(
    www.baidu.com
    blog.51cto.com
    www.taobao.com
    www.192.168.80.123.com
    )
    
    waits(){
            echo -n "3s run after"
            for((i=0;i<3;i++))
            do
                    echo -n .
                    sleep 1
            done
            echo 
    }
    
    url(){
            waits
            for((i=0; i<`echo ${#url_list[*]}`; i++))
            do
              wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]}>/dev/null 2>&1
                    if [ $? -eq 0 ];then
                            action "${url_list[$i]}" /bin/true
                    else
                            action "${url_list[$i]}" /bin/false
                    fi
    
            done
            ((count++))
    }
    
    main(){
            while true
            do
              url
              echo "------count:$count------"
              sleep 10
            done
    }
    main
    while 循环按行读文件

    方法一:

    cat 文件|while read line
    do
      命令
    done

    方法二:

    while read line
    do
      命令
    done<文件

    案例一:
    编写一个 shell 脚本,实现 cat 命令的基本功能

    #!/bin/bath
    while read line
    do
      echo $line
    done</home/shell/fun.sh

    案例二:
    编写 shell 脚本,根据短时间内的 PV 量封掉对应 ip,解决类 DoS 的功能

    #!/bin/bash
    count=0
    while true
    do
    netstat -an|grep EST|awk -F '[ :]+' '{print $6}'|sort|uniq -c>ip.log
    exec<ip.log
    while read line
    do
            pv=`echo $line|awk '{print $1}'`
            ip=`echo $line|awk '{print $2}'`
            if [ $pv -gt 10 ]&&[ `iptables -nL|grep $ip|wc -l` -eq 0 ];then
                    iptables -t filter -I INPUT -s $ip -j DROP
                    echo "sun success"
            fi
    done
            ((count++))
    sleep 10
    echo "---$count---"
    done

    转载于:https://blog.51cto.com/12384628/2297292

    展开全文
  • 正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)是用于描述字符串规则的工具。换句话说,正则表达式就是记录文本规则的代码。 正则表达式语言由两种基本字符类型组成:原义(正常)...

    1.正则表达式到底是什么东西?

    正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)是用于描述字符串规则的工具。换句话说,正则表达式就是记录文本规则的代码。

    正则表达式语言由两种基本字符类型组成原义(正常)文本字符元字符(metacharacter)。元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

    在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是 * 和 ? 。如果你想查找某个目录下的所有的Word文档的话,你会搜索*.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——比如你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。

    2.常用正则表达式符号

    (1)常用的元字符
    \b 代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。
    . 匹配除了换行符以外的任意字符。
    \d 匹配一位数字(0,或1,或2,或……)。
    \s 匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。
    \w 匹配字母或数字或下划线或汉字等。
    ^ 匹配字符串的开始。
    $ 匹配字符串的结束。有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配行的开始处和结束处。

    (2)常用的限定符
    * 代表数量——指定 * 前边的内容可以连续重复使用任意次以使整个表达式得到匹配。
    .* 连在一起就意味着任意数量的不包含换行的字符。
    + 是和 * 类似的元字符,不同的是: * 匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。
    ? 重复零次或一次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次
    [] 匹配没有预定义元字符的字符集合。
    例如:
    [0-9] 代表一位数字,与\d就是完全一致的;
    [a-z0-9A-Z_] 完全等同于\w(如果只考虑英文的话)。
    [.?!] 匹配标点符号( . 或 ? 或 ! )

    (3)常用的反义代码
    \W 匹配任意不是字母,数字,下划线,汉字的字符
    \S 匹配任意不是空白符的字符
    \D 匹配任意非数字的字符
    \B 匹配不是单词开头或结束的位置
    [^x] 匹配除了x以外的任意字符
    [^aeiou] 匹配除了aeiou这几个字母以外的任意字符

    (4)常用分组语法
    捕获:
    (exp) 匹配exp,并捕获文本到自动命名的组里
    (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name’exp)
    (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
    零宽断言:
    (?=exp) 匹配exp前面的位置
    (?<=exp) 匹配exp后面的位置
    (?!exp) 匹配后面跟的不是exp的位置
    (?<!exp) 匹配前面不是exp的位置
    注释:
    (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

    (5)懒惰限定符
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复

    3.正则表达式详细介绍

    字符转义
    如果你想查找元字符本身的话,比如查找 . ,或者 * ,是没办法直接指定它们的,因为它们会被解释成别的意思。这时你就得使用 \ 来取消这些字符的特殊意义。因此,应该使用 \. 和 \* 。当然,要查找 \ 本身,得用 \\。
    例如:china\.net 匹配 china.net,C:\\Windows匹配C:\Windows。

    分枝条件
    正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。具体方法是用 | 把不同的规则分隔开。

    我们来看一个复杂的表达式:\(?0\d{2}[) -]?\d{8}
    “(” 和 “)” 也是元字符,所以在这里需要使用转义。这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符 \( ,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是 ) 或 - 或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。

    不幸的是,刚才那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看例子:
    0\d{2}-\d{8}|0\d{3}-\d{7} 这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。

    (0\d{2})[- ]?\d{8}|0\d{2}[- ]?\d{8} 这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。

    \d{5}-\d{4}|\d{5} 这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

    分组
    我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。例如:
    (\d{1,3}.){3}\d{1,3} 是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
    不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:(2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?
    (PS: IP地址中每个数字都不能大于255。IP 地址里的数字可以包含有前导 0 (leading zeroes),所以01.02.03.04 这样前面带有0的数字, 是正确的IP地址。)

    反义
    有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义。
    常用的反义正则表达式:
    \W 匹配任意不是字母,数字,下划线,汉字的字符
    \S 匹配任意不是空白符的字符
    \D 匹配任意非数字的字符
    \B 匹配不是单词开头或结束的位置
    [^x] 匹配除了x以外的任意字符
    [^aeiou] 匹配除了aeiou这几个字母以外的任意字符
    例子:\S+ 匹配不包含空白符的字符串。
    <a[^>]+> 匹配用尖括号括起来的以a开头的字符串。

    后向引用
    后向引用用于重复搜索前面某个分组匹配的文本。使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。例如,\1代表分组1匹配的文本。

    请看一个较为复杂的示例:
    \b(\w+)\b\s+\1\b 可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容,也就是前面匹配的那个单词(\1)。

    你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成 ’ 也行:(?‘Word’\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。

    (?:exp) 不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权。

    常用的捕获正则表达式 :
    (exp) 匹配exp,并捕获文本到自动命名的组里
    (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name’exp)
    (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号

    零宽断言
    零宽断言指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。
    它用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此被称为零宽断言。

    下面给出几个例子:
    (?=exp) 也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如:
    \b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),例如查找I’m singing while you’re dancing.时,它会匹配sing和danc。
    (?<=exp) 也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如:
    (?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
    (?<=\s)\d+(?=\s) 匹配以空白符间隔的数字(再次强调,不包括这些空白符)。

    常用的零宽断言正则表达式:
    (?=exp) 匹配exp前面的位置
    (?<=exp) 匹配exp后面的位置
    (?!exp) 匹配后面跟的不是exp的位置
    (?<!exp) 匹配前面不是exp的位置

    负向零宽断言
    前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词–它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
    \b\w*q[^u]\w*\b 匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。

    下面给出几个例子:
    (?!exp) 零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d) 匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b 匹配不包含连续字符串abc的单词。
    (?<!exp) 零宽度负回顾后发断言,断言此位置的前面不能匹配表达式exp。例如:(?<![a-z])\d{7} 匹配前面不是小写字母的七位数字。

    一个更复杂的例子:
    (?<=<(\w+)>).*(?=<\/\1>) 匹配不包含属性的简单HTML标签内里的内容。(?<=<(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<\b>),然后是 .* (任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<\b>的话,后缀就是</b>了。整个表达式匹配的是< b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。

    注释
    (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
    小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。

    贪婪与懒惰
    当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

    有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样 .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:

    a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。

    常用的懒惰正则表达式:
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复

    本文部分引自:https://deerchao.net/tutorials/regex/regex.htm
    推荐一款在线的正则表达式调试工具:https://regex101.com/

    展开全文
  • 在日常业务系统开发中,我们往往需要根据多个条件进行内容的筛选工作,比如商城系统中的根据销量、价格、评价、好评度、位置等信息进行筛选,...这时,巧妙利用表达式树就可以轻松解决这个问题,尤其是在使用EF等OR...

    在日常业务系统开发中,我们往往需要根据多个条件进行内容的筛选工作,比如商城系统中的根据销量、价格、评价、好评度、位置等信息进行筛选,最简单的方法我们可以通过if else来进行操作,但由于这些筛选选项都是可选可不选的,所以要把所有的筛选条件都考虑进去的话,if else的方式会很麻烦(需要写很多if else判断)而且代码会很乱。这时,巧妙利用表达式树就可以轻松解决这个问题,尤其是在使用EF等ORM框架的时候。 我这里对Expression表达树进行了一个扩展封装,来满足我们日常项目内容筛选的需求:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace Project.Common
    {
        /// <summary>
        /// 谓词表达式构建器
        /// </summary>
        public static class ExpressionExtensions
        {
            /// <summary>
            /// 创建一个值恒为 <c>true</c> 的表达式。
            /// </summary>
            /// <typeparam name="T">表达式方法类型</typeparam>
            /// <returns>一个值恒为 <c>true</c> 的表达式。</returns>
            public static Expression<Func<T, bool>> True<T>() { return p => true; }
    
            /// <summary>
            /// 创建一个值恒为 <c>false</c> 的表达式。
            /// </summary>
            /// <typeparam name="T">表达式方法类型</typeparam>
            /// <returns>一个值恒为 <c>false</c> 的表达式。</returns>
            public static Expression<Func<T, bool>> False<T>() { return f => false; }
    
            /// <summary>
            /// 使用 Expression.OrElse 的方式拼接两个 System.Linq.Expression。
            /// </summary>
            /// <typeparam name="T">表达式方法类型</typeparam>
            /// <param name="left">左边的 System.Linq.Expression 。</param>
            /// <param name="right">右边的 System.Linq.Expression。</param>
            /// <returns>拼接完成的 System.Linq.Expression。</returns>
            public static Expression<T> Or<T>(this Expression<T> left, Expression<T> right)
            {
                return MakeBinary(left, right, Expression.OrElse);
            }
    
            /// <summary>
            /// 使用 Expression.AndAlso 的方式拼接两个 System.Linq.Expression。
            /// </summary>
            /// <typeparam name="T">表达式方法类型</typeparam>
            /// <param name="left">左边的 System.Linq.Expression 。</param>
            /// <param name="right">右边的 System.Linq.Expression。</param>
            /// <returns>拼接完成的 System.Linq.Expression。</returns>
            public static Expression<T> And<T>(this Expression<T> left, Expression<T> right)
            {
                return MakeBinary(left, right, Expression.AndAlso);
            }
    
            /// <summary>
            /// 使用自定义的方式拼接两个 System.Linq.Expression。
            /// </summary>
            /// <typeparam name="T">表达式方法类型</typeparam>
            /// <param name="left">左边的 System.Linq.Expression 。</param>
            /// <param name="right">右边的 System.Linq.Expression。</param>
            /// <param name="func"> </param>
            /// <returns>拼接完成的 System.Linq.Expression。</returns>
            private static Expression<T> MakeBinary<T>(this Expression<T> left, Expression<T> right, Func<Expression, Expression, Expression> func)
            {
                Debug.Assert(func != null, "func != null");
                return MakeBinary((LambdaExpression)left, right, func) as Expression<T>;
            }
    
            /// <summary>
            /// 拼接两个 <paramref>
            ///        <name>System.Linq.Expression</name>
            ///      </paramref>  ,两个 <paramref>
            ///                         <name>System.Linq.Expression</name>
            ///                       </paramref>  的参数必须完全相同。
            /// </summary>
            /// <param name="left">左边的 <paramref>
            ///                          <name>System.Linq.Expression</name>
            ///                        </paramref> </param>
            /// <param name="right">右边的 <paramref>
            ///                           <name>System.Linq.Expression</name>
            ///                         </paramref> </param>
            /// <param name="func">表达式拼接的具体逻辑</param>
            /// <returns>拼接完成的 <paramref>
            ///                  <name>System.Linq.Expression</name>
            ///                </paramref> </returns>
            private static LambdaExpression MakeBinary(this LambdaExpression left, LambdaExpression right, Func<Expression, Expression, Expression> func)
            {
                var data = Combinate(right.Parameters, left.Parameters).ToArray();
                right = ParameterReplace.Replace(right, data) as LambdaExpression;
                Debug.Assert(right != null, "right != null");
                return Expression.Lambda(func(left.Body, right.Body), left.Parameters.ToArray());
            }
    
            private static IEnumerable<KeyValuePair<T, T>> Combinate<T>(IEnumerable<T> left, IEnumerable<T> right)
            {
                var a = left.GetEnumerator();
                var b = right.GetEnumerator();
                while (a.MoveNext() && b.MoveNext())
                    yield return new KeyValuePair<T, T>(a.Current, b.Current);
            }
        }
    
        #region class: ParameterReplace
        internal sealed class ParameterReplace : ExpressionVisitor
        {
            public static Expression Replace(Expression e, IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>> paramList)
            {
                var item = new ParameterReplace(paramList);
                return item.Visit(e);
            }
    
            private readonly Dictionary<ParameterExpression, ParameterExpression> _parameters;
    
            public ParameterReplace(IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>> paramList)
            {
                _parameters = paramList.ToDictionary(p => p.Key, p => p.Value, new ParameterEquality());
            }
    
            protected override Expression VisitParameter(ParameterExpression p)
            {
                ParameterExpression result;
                if (_parameters.TryGetValue(p, out result))
                    return result;
                return base.VisitParameter(p);
            }
    
            #region class: ParameterEquality
            private class ParameterEquality : IEqualityComparer<ParameterExpression>
            {
                public bool Equals(ParameterExpression x, ParameterExpression y)
                {
                    if (x == null || y == null)
                        return false;
    
                    return x.Type == y.Type;
                }
    
                public int GetHashCode(ParameterExpression obj)
                {
                    if (obj == null)
                        return 0;
    
                    return obj.Type.GetHashCode();
                }
            }
            #endregion
        }
        #endregion
    }
    

     

    展开全文
  • JavaScript之选择控制语句(if,switch,while,do-while,for循环)及很重要的表达式真与假 前言 您将在本文当中学习到 顺序语句 分支语句 If判断,switch,while循坏,do..while循环,for循环,表达式中的真...
  • 2、值1和值2中又可以是条件表达式,可以嵌套条件表达式。如 变量 = (布尔表达式)?值1 : (布尔表达式2)?值2:值3; 3、当括号内的表达式为真则变量为冒号前面的值,否则为冒号后面的值。 4、符号?和:在表达式...
  • Python while循环语句详解

    千次阅读 2019-08-14 18:42:38
    Python 中,while 循环和 if 条件分支语句...while 条件表达式: 代码块 这里的代码块,还是指的缩进格式相同的多行代码,不过在循环结构中,它又称为循环体。 while 语句执行的具体流程为:首先判断条件表达式...
  • C语言

    万次阅读 多人点赞 2019-12-18 23:01:50
    条件表达式中三个表达式的类型可以不同 120.switch语句是多分支选择语句 121.switch语句中每一个case的常量表达式的值必须互不相同 122.switch语句执行完一个case后面的语句后,流程控制转移到下一个case继续执行 ...
  • 关于C语言while循环语句的定义、使用、功能、注意事项等
  • C语言条件判断语句:if、else if、else

    万次阅读 多人点赞 2018-07-05 13:34:04
    1)简单介绍三种形式的条件判断语句:if、else if、elseif:if(表达式) 执行语句if:判断表达式内容,如果为true(真),就执行语句else if:if(表达式) 执行语句 else if(表达式1) 执行语句1 ......(很多的else if)...
  • C#语言

    千次阅读 2019-11-08 10:54:13
    ​ do-while循环:先执行依次循环再判断条件表达式是否成立。若条件成立,则继续循环;否则结束循环。 ​ for循环:必须使用整型变量做循环计算器,通过条件表达式限定计数器变量值来控制循环。 ​ foreach循环...
  • C语言程序设计(第二版) 练习2-10 个人设计练习2-10 重新编写将大写字母转换为小写字母的函数lower,并用条件表达式替代其中的if-else结构。代码块#include <stdio.h>int lower(char x);main() { char c, b;...
  • Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为: while 判断条件: 执行语句…… 执行语句可以是单个语句或语句块。判断条件可以是...
  • Python内置函数

    万次阅读 多人点赞 2019-05-10 15:10:36
    any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。 元素除了是 0、空、False 外都算 True。 any() 方法的语法: any(iterable) 参数: ...
  • Java的while语句

    千次阅读 2020-05-23 07:25:22
    循环是程序中的重要流程结构之一。 循环语句能够使程序代码重复执行,适用于...初始化语句(init statement): 一条或多条语句,这些语句用于完成一些初始化工 作,初始化语句在循环开始之前执行。 循环条件(te
  • 循环结构  循环结构是程序中一种很重要的结构。其特点是,在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复...维持循环的是一个条件表达式,条件成立执行循环体,条件不成
  • 正则表达式教程及常用正则表达式

    千次阅读 2016-12-07 01:22:52
    正则表达式教程、常用正则表达式以及正则表达式测试工具
  • Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为: 执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零、或非空(null...
  • 四、while和dowhile循环结构

    千次阅读 2020-01-18 15:52:51
    while循环结构 dowhile循环结构 循环语句也叫迭代语句,是指在循环条件满足的情况下,重复执行一组代码块...while ( 条件表达式) { 循环体; } 注意: 当条件表达式的结果为真的时候,执行内部循环体;然后再...
  • Python re模块 (正则表达式用法剖析详解)

    千次阅读 多人点赞 2019-10-23 20:18:51
    Python re模块不等于正则表达式!文章整理了re模块的用法,收集整理了正则表达式的内容,详细的解读了正则表达式的用法,例举了re模块如何使用到正则表达式
  • Python流程控制语句

    2019-09-29 20:17:49
     其中,表达式可以是一个单纯的布尔值或变量,也可以是比较表达式或逻辑表达式,如果表达式为真,则执行“语句块”;如果表达式的值为假,就跳 过“语句块”,继续执行后面的语句。 2、if…else语句if…else 语句...
  • 文章目录1.表达式2. 用表达式定义值和变量3. 表达式块4.语句5. if...else表达式块6....表达式是返回一个值的代码单元 简单表达式的例子: 更复杂的表达式的例子: 表达式最重要的是它返回的值,...
  • 问题如标题,使用正则表达式匹配字段目前无非就三种,分别是: re.match() re.search() re.findall() 简单介绍一下,re.match()与re.search()非常类似,主要区别就是前者是从目标字符串的开头匹配,而后者则要没有...
  • while语句

    2020-03-13 21:02:00
    while(条件表达式)——————>循环条件 { 语句组;————————>循环体 } 含义:当条件表达式为真就重复执行语句组 while循环又称“当型循环”,既先测试循环条件在执行循环体。当条件成立时才执行后面的...
  • if 语句: 作用:让程序根据条件选择性的执行某条语句或某些语句 说明:if语句又叫条件语句,也叫分支语句 语法:if 真值表达式1; 语句块1 elif 真值表达式2: 语句块2 elif 真值表达式3: 语句块3 ... ...
  • Java循环语句

    千次阅读 多人点赞 2019-07-09 11:34:09
    循环就是在循环条件满足的情况下,反复执行特定代码。 1.2 为什么要使用循环 当我们要打印100次helloworld 或者我们想实现1-10的和 1+2+3+4+5.... int sum = 0; sum = sum + 1; sum = sum + 2; sum = sum + 3; sum ...
  • -------------小编学习pytho第三天总结------------- 三元表达式 格式: 变量 = 条件为真返回真的结果 if 条件 else 条件为假返回的结果 ...格式:while 条件: 循环体 while循环后面跟else其目的是在于,如果w
  • 【MATLAB】MATLAB的基础知识

    千次阅读 多人点赞 2017-04-12 11:52:00
    表达式是一个矩阵,语句组则是一组合法的MATLAB命令。 for循环语句则执行过程是:从表达式的第一列开始,依次将表达式(矩阵)的各列之值赋值给变量,然后执行语句组中的语句,直到最后一列。 for 语句的...
  • while&until循环详解

    千次阅读 2018-02-10 19:16:24
    循环语句命令常用于执行一条指令或者一组指令,那么直到条件不在满足时停止,在shell脚本中循环语句常见有 while until for select循环语句。 在while循环语句主要用来重复执行一组命令或语句,在...条件表达式&g...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,666
精华内容 45,866
关键字:

while用于条件的表达式是