精华内容
下载资源
问答
  • 本文将介绍一段实例代码,来讲解利用正则表达式使C#判断输入日期格式是否正确的方法。希望这段代码能对大家有所帮助。  通常我们在用C#编写系统程序或者Web开发时,都会遇到需要验证输入的字符串是否是日期的情况...
  • 判断一个字符是不是汉字通常有三种方法,第一种用 ASCII 码判断,第二种用汉字的UNICODE编码范围判断,第三种用正则表达式判断,以下是具体方法
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼C语言研究性学习的路线现行的多数C语言教材有太多的误区,不仅不能给读者提供有效的学习线索,还常常...二、 表达式的求值(一)基础知识在后面加一个分号(;),C语言表...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

    C语言研究性学习的路线

    现行的多数C语言教材有太多的误区,不仅不能给读者提供有效的学习线索,还常常“误导”读者,于是,“死记硬背”便成了学习C语言的唯一选择。本文

    以拙作《新编C语言程序设计教程》(清华大学出版社出版,配套视频zeq126.56.com)为基础,探讨了C语言的研究性学习。

    二、 表达式的求值

    (一)基础知识

    在后面加一个分号(;),C语言表达式就变成了C语句,此时计算机执行C语句的过程就是对表达式求值的过程,因此表达式求值实际上模拟了计算机的计算。

    C语言表达式的重要特征是每个表达式都有一个确定的值及类型。求值时需根据操作符的优先级和结合性来确定运算顺序。能否顺利地求出表达式的值可作为判断C语言表达式是否合法的依据。

    从表3-1可知,C语言操作符的种类繁多,但是数学上常见的一些运算在C语言中却并没有相关的操作符,如求平方根、求绝对值、幂运算等,不过C语言提

    供了相应功能的库函数,如sqrt函数、fabs函数、pow函数等。与printf函数类似,使用这些库函数需要在程序中包含math.h头文件

    (#include )。

    重点:

    1. 每个表达式都有一个确定的值。

    2. 利用数学库函数写出常见的数学式子。

    3. 查表根据优先级和结合性利用加括号的方式确定复杂的表达式的求值顺序,如3+5*2为(3+(5*2));i=j=k=23为(i=(j=(k=23)))。

    (二)赋值表达式

    赋值操作符的优先级倒数第二,右结合。

    重点:

    1. 赋值操作符“=”读作“赋值为”。

    2. i=i+1;i=j;的执行过程。

    3. 如何判断表达式i=j=k=23的合法性。

    4. 理解复合赋值操作符的本质,如i*=a+b;。

    难点:

    类型不匹配时的赋值操作。

    1. 整型之间相互赋值

    1.1 编码长度相同,但有无符号数和有符号数的区别,如unsigned

    short型和short型,此时只是简单地把被赋值变量的状态设置成赋值变量的存储状态。赋值后两者的值通常不同,如有unsigned uh;

    short h=-1; ,则uh=h;后uh的值为65535。

    1.2 编码长度不同,如long型与short型或unsigned

    short型。以a=b为例,又分两种情况。当b的编码长度小于a时,赋值原则为赋值后两者的值相同。如有long l; unsigned short

    uh=65535; short

    h=-1;则l=uh后,l的值为65535;而l=h后,l的值为-1。由练习2.6可知,编码长度增加而值不变时编码的变化规律。当b的编码长度大于

    a时,赋值操作只能使a的状态与b的部分字节状态一致,舍弃了b中高位的状态,赋值后两者的值通常不同。

    2. 整型与浮点型之间的相互赋值

    整数可以看作是小数部分为0的浮点数,而浮点型变量向整型变量赋值时会舍弃小数部分。

    注意:

    1. 编程时尽量使用安全的赋值操作。(赋值后两者的值相等)

    2. 应理解类型不匹配时的赋值原则。

    (三)算术表达式

    C语言中算术操作符的优先级和结合性虽然和数学上的一致。但由于计算机中不同类型数据的编码格式不同,当类型不同的操作数混合运算时,得出与计算机一致的结果也并非易事。

    先讨论整型间的算术运算。

    表达式求值通常在运算器中进行,而运算器中专用存储单元的长度是固定的,因此,整型间运算时,当操作数的编码长度“不够”长时会被自动扩充成相应的长度。需注意两点:

    1. 短变长是安全的“赋值操作”。

    2. C语言中这个长度是“逻辑的”,即编译系统中int型的长度,而非计算机的实际长度。int型在TC中是2个字节,在VC6.0中是4个字节。

    这也就意味着同样的代码可能可能在TC中不需扩充而直接计算,但在VC6.0中则需要扩充后才能计算。当然,字符型进行算术运算时被看作只有1个字节的整

    型,无论如何都会被扩充的。

    展开全文
  • 1、语法: if commands; then commands; [else if commands; then commands;... 计算其后的命令即 commands的退出状态是成功还是失败,并据此判断下一步该执行哪些commands >if ...

    1、语法:

     if  commands;
          then     commands;
     [else if commands;
          then commands;
     ]
    [ else commands;]
     fi
    

    2、if 语句真正做的是:

     计算其后的命令即 commands的退出状态是成功还是失败,并据此判断下一步该执行哪些commands
          >if     true;then     echo "it's true"
               it's true
    

    3、test 命令:

    1)、 if 后面的commands 通常是test命令,test命令执行各种各样的检查与比较。它有两种等价形式,如下:
    
     test expression     等价于     [ expression ]
    
     因此:
    
     if [ $x = 5 ]     等价于     if     test     $x = 5
    
     但中括号的形式比较流行。
    
     2)test命令的返回结果:
    
     test 后的expression是一个表达式,其执行结果是true 或者false 。
     当表达式的执行结果是true时,test命令的退出状态是零。
     当表达式的执行结果是false时,test命令的退出状态是1。
    

    4、[[]] 、(())

      1)[[]]是test命令的加强版
          [[]]增加了对一个重要的新的字符串表达式的支持:string1 =~ regex,这个expression是测试字符串是否符合所给正则。
          另一个功能是,支持==操作符用作类型匹配。
    
              [hadoop@hadoop03 bin]$ x=$(ls)
               [hadoop@hadoop03 bin]$ if [[ $x == iftest.* ]] ;then echo "file matches pattern iftest.* ";fi;
               file matches pattern iftest.*
    
    
     2)(())也是test命令的加强版,它 是为整数设计的,支持一套完整的算术运算:
    
          [hadoop@hadoop03 bin]$ x=5
          [hadoop@hadoop03 bin]$ if (( $x%2 == 0 )) ;then echo "ou shu";fi;
          [hadoop@hadoop03 bin]$ if (( $x%2 != 0 )) ;then echo "ou shu";fi;
          ou shu
    

    5、&& 和 || 和 !
    1)当两者用在expression中时,是将表达式进行结合: [ expression1 && expression2 ];

     2)当用来结合expression时,必须是用在如下形式的测试中:[],或者[[]],或者(())中,
          如果是用在 test 命令形式的测试中时,用一下运算符取代
          &&     ||     !
          -a     -o       !
    

    释意:and or not

     2)两者也可以用来连接 多个command: command1 && command2;
          此时遵循一个短路规则,当command1退出状态为零时,不会再执行command2
    

    4、文件表达式

    表达式如果为真
    file1 -ef file2file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)。
    file1 -nt file2file1新于 file2。
    file1 -ot file2file1早于 file2。
    -b filefile 存在并且是一个块(设备)文件。
    -c filefile 存在并且是一个字符(设备)文件。
    -d filefile 存在并且是一个目录。
    -e filefile 存在。
    -f filefile 存在并且是一个普通文件。
    -g filefile 存在并且设置了组 ID。
    -G filefile 存在并且由有效组 ID 拥有。
    -k filefile 存在并且设置了它的“sticky bit”。
    -L filefile 存在并且是一个符号链接。
    -O filefile 存在并且由有效用户 ID 拥有。
    -p filefile 存在并且是一个命名管道。
    -r filefile 存在并且可读(有效用户有可读权限)。
    -s filefile 存在且其长度大于零。
    -S filefile 存在且是一个网络 socket。
    -t fdfd 是一个定向到终端/从终端定向的文件描述符 。 这可以被用来决定是否重定向了标准输入/输出错误。
    -u filefile 存在并且设置了 setuid 位。
    -w filefile 存在并且可写(有效用户拥有可写权限)。
    -x filefile 存在并且可执行(有效用户有执行/搜索权限)。

    字符串表达式

    表达式如果为真
    stringstring 不为 null。
    -n string字符串 string 的长度大于零。
    -z string字符串 string 的长度为零。
    string1 = string2 string1 == string2string1 和 string2 相同. 单或双等号都可以,不过双等号更受欢迎。
    string1 != string2string1 和 string2 不相同。
    string1 > string2sting1 排列在 string2 之后。
    string1 < string2string1 排列在 string2 之前。

    警告:这个 > 和 <表达式操作符必须用引号引起来(或者是用反斜杠转义), 当与 test 一块使用的时候。如果不这样,它们会被 shell 解释为重定向操作符,造成潜在地破坏结果。 同时也要注意虽然 bash 文档声明排序遵从当前语系的排列规则,但并不这样。将来的 bash 版本,包含 4.0, 使用 ASCII(POSIX)排序规则。

    整型表达式

    表达式如果为真…
    integer1 -eq integer2integer1 等于 integer2.
    integer1 -ne integer2integer1 不等于 integer2.
    integer1 -le integer2integer1 小于或等于 integer2.
    integer1 -lt integer2integer1 小于 integer2.
    integer1 -ge integer2integer1 大于或等于 integer2.
    integer1 -gt integer2integer1 大于 integer2.

    这里是一个演示以上表达式用法的脚本:

    #!/bin/bash# test-integer: evaluate the value of an integer.
    INT=-5
    if [ -z "$INT" ]; then
        echo "INT is empty." >&2
        exit 1
    fiif [ $INT -eq 0 ]; then
        echo "INT is zero."else
        if [ $INT -lt 0 ]; then
            echo "INT is negative."
        else
            echo "INT is positive."
        fi
        if [ $((INT % 2)) -eq 0 ]; then
            echo "INT is even."
        else
            echo "INT is odd."
        fifi

    这个脚本中有趣的地方是怎样来确定一个整数是偶数还是奇数。通过用模数2对数字执行求模操作, 就是用数字来除以2,并返回余数,从而知道数字是偶数还是奇数。

    展开全文
  • C语言正则表达式判断例程

    千次阅读 2018-07-07 10:14:15
    标准的C和C++都不支持正则表达式,但有正则表达式的函数库提供这功能.C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror()。使用正则表达式步骤:1)编译正则表达式 regcomp()2)匹配正则...
    标准的C和C++都不支持正则表达式,但有正则表达式的函数库提供这功能.
    
    C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror()。
    使用正则表达式步骤:
    1)编译正则表达式 regcomp()
    2)匹配正则表达式 regexec()
    3)释放正则表达式 regfree()


    4)获取regcomp 或者regexec 产生错误,获取包含错误信息的字符串


    函数声明如下:
    1、int regcomp (regex_t *compiled, const char *pattern, int cflags)
    这个函数把指定的正则表达式pattern编译成一种特定的数据格式(参数regex_t *compiled),这样可以使匹配更有效。


    函数regexec 会使用这个数据在目标文本串中进行模式匹配。执行成功返回0。  


    参数说明:
    ①regex_t 是一个结构体数据类型,用来存放编译后的正则表达式,它的成员re_nsub 用来存储正则表达式中的子正则表达式的个数,子正则表达式就是用圆括号包起来的部分表达式。
    ②pattern 是指向我们写好的正则表达式的指针。
    ③cflags 有如下4个值或者是它们或运算(|)后的值:
    REG_EXTENDED 以功能更加强大的扩展正则表达式的方式进行匹配。
    REG_ICASE 匹配字母时忽略大小写。
    REG_NOSUB 不用存储匹配后的结果。
    REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。


    2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)
    当我们编译好正则表达式后,就可以用regexec 匹配我们的目标文本串了,如果在编译正则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文本串当作一个字符串处理。执行成功返回0。
    regmatch_t 是一个结构体数据类型,在regex.h中定义:             
    typedef struct
    {
       regoff_t rm_so;
       regoff_t rm_eo;
    } regmatch_t;
    成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。


    通常我们以数组的形式定义一组这样的结构。因为往往我们的正则表达式中还包含子正则表达式。数组0单元存放主正则表达式位置,后边的单元依次存放子正则表达式位置。


    参数说明:


    ①compiled 是已经用regcomp函数编译好的正则表达式。
    ②string 是目标文本串。
    ③nmatch 是regmatch_t结构体数组的长度。
    ④matchptr regmatch_t类型的结构体数组,存放匹配文本串的位置信息。
    ⑤eflags 有两个值


    REG_NOTBOL不匹配行的开头,除非在 regcomp 编译时 cflag 设置 REG_NEWLINE。'^'匹配行的开头 , 不管 regexec 中是否设置 eflags 为 REG_NOTBOL 。


    REG_NOTEOL不匹配行的结束,除非在 regcomp 编译时 cflag 设置 REG_NEWLINE 。'$' 匹配行的末尾 , 不管 regexec 中是否设置 eflags 为 REG_NOTEOL 。


    3. void regfree (regex_t *compiled)
    当我们使用完编译好的正则表达式后,或者要重新编译其他正则表达式的时候,我们可以用这个函数清空compiled指向的regex_t结构体的内容,请记住,如果是重新编译的话,一定要先清空regex_t结构体。






    4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)


    当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。
    参数说明:
    ①errcode 是由regcomp 和 regexec 函数返回的错误代号。
    ②compiled 是已经用regcomp函数编译好的正则表达式,这个值可以为NULL。
    ③buffer 指向用来存放错误信息的字符串的内存空间。
    ④length 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。
    size_t length = regerror (errcode, compiled, NULL, 0);


    匹配Email的示例:
    #include <stdio.h>
    #include <sys/types.h>
    #include <regex.h>
     
    int main(int argc,char** argv)
    {
    int status ,i;
    int cflags = REG_EXTENDED;
    regmatch_t pmatch[1];
    const size_t nmatch = 1;
    regex_t reg;
    const char * pattern = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*.\\w+([-.]\\w+)*$";
    char * buf = "chenjiayi@126.com";
    regcomp(&reg,pattern,cflags);//编译正则模式
    status = regexec(&reg,buf,nmatch,0);//执行正则表达式和缓存的比较
    if(status == REG_NOMATCH)
    printf("No match\n");
    else if (0 == status)
    {
    printf("比较成功:");
    for(i = pmatch[0].rm_so;i<pmatch[0].rm_eo;++i)putchar(buf[i]);
    printf("\n");
    }
    regfree(&reg);
    return 0;
    }




    正则表达式 由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义。
    在最简单的情况下,一个正则表达式看上去就是一个普通的查找串。


    例如,正则表达式"testing"中没有包含任何元字符,它可以匹配"testing"和"testing123"等字符串,但是不能匹配"Testing"。
    元字符描述如下:


    元字符
    描述
    \
    将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“\\n”匹配\n。“\n”匹配换行符。序列“\\”匹配“\”而“\(”则匹配“(”。
    ^
    匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
    $
    匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
    *
    匹配前面的子表达式零次或多次(大于等于0次)。例如,zo*能匹配“z”,“zo”以及“zoo”。*等价于{0,}。
    +
    匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
    ?
    匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
    {n}
    n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
    {n,}
    n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
    {n,m}
    m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
    ?
    当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
    .点
    匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
    (pattern)
    匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“”或“”。
    (?:pattern)
    匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
    (?=pattern)
    正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
    (?!pattern)
    正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
    (?<=pattern)
    反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
    (?<!pattern)
    反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
    x|y
    匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
    [xyz]
    字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
    [^xyz]
    负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。
    [a-z]
    字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
    注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
    [^a-z]
    负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
    \b
    匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
    \B
    匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
    \cx
    匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
    \d
    匹配一个数字字符。等价于[0-9]。
    \D
    匹配一个非数字字符。等价于[^0-9]。
    \f
    匹配一个换页符。等价于\x0c和\cL。
    \n
    匹配一个换行符。等价于\x0a和\cJ。
    \r
    匹配一个回车符。等价于\x0d和\cM。
    \s
    匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
    \S
    匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
    \t
    匹配一个制表符。等价于\x09和\cI。
    \v
    匹配一个垂直制表符。等价于\x0b和\cK。
    \w
    匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
    \W
    匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
    \xn
    匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
    \num
    匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
    \n
    标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
    \nm
    标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
    \nml
    如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
    \un
    匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(&copy;)。
    \< \> 匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\<the\>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
    将 和 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
    | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。
    + 匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。
    ? 匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。
    {i} {i,j} 匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]{3} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]{4,6} 匹配连续的任意4个、5个或者6个数字


    等价字符:
    ?,*,+,\d,\w 都是等价字符
    ?等价于匹配长度{0,1}
    *等价于匹配长度{0,} 
    +等价于匹配长度{1,}
    \d等价于[0-9]
    \w等价于[A-Za-z_0-9]


    常用运算符与表达式:
    ^ 开始
    () 域段
    [] 包含,默认是一个字符长度
    [^] 不包含,默认是一个字符长度
    {n,m} 匹配长度 
    . 任何单个字符(\. 字符点)
    | 或
    \ 转义
    $ 结尾
    [A-Z] 26个大写字母
    [a-z] 26个小写字母
    [0-9] 0至9数字
    [A-Za-z0-9] 26个大写字母、26个小写字母和0至9数字


    分割语法:
    [A,H,T,W] 包含A或H或T或W字母
    [a,h,t,w] 包含a或h或t或w字母
    [0,3,6,8] 包含0或3或6或8数字


    语法与释义:
    基础语法 "^([]{})([]{})([]{})$"
    正则字符串 = "开始([包含内容]{长度})([包含内容]{长度})([包含内容]{长度})结束" 
    ?,*,+,\d,\w 这些都是简写的,完全可以用[]和{}代替,在(?:)(?=)(?!)(?<=)(?<!)(?i)(*?)(+?)这种特殊组合情况下除外。


    简写实例:
    字符串;tel:086-0666-88810009999
    原始正则:"^tel:[0-9]{1,3}-[0][0-9]{2,3}-[0-9]{8,11}$" 
    速记理解:开始 "tel:普通文本"[0-9数字]{1至3位}"-普通文本"[0数字][0-9数字]{2至3位}"-普通文本"[0-9数字]{8至11位} 结束"
    等价简写后正则写法:"^tel:\d{1,3}-[0]\d{2,3}-\d{8,11}$" ,简写语法不是所有语言都支持。


    实例应用
    1.验证用户名和密码:("^[a-zA-Z]\w{5,15}$")正确格式:"[A-Z][a-z]_[0-9]"组成,并且第一个字必须为字母6~16位;
    2.验证电话号码:("^(\\d{3,4}-)\\d{7,8}$")正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx;
    3.验证手机号码:"^1[3|4|5|7|8][0-9]\\d{8}$";
    4.验证身份证号(15位或18位数字):"\\d{14}[[0-9],0-9xX]";
    5.验证Email地址:("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\.\\w+([-.]\\w+)*$");
    6.只能输入由数字和26个英文字母组成的字符串:("^[A-Za-z0-9]+$") ;
    7.整数或者小数:^[0-9]+([.]{0,1}[0-9]+){0,1}$
    8.只能输入数字:"^[0-9]*$"。
    9.只能输入n位的数字:"^\\d{n}$"。
    10.只能输入至少n位的数字:"^\\d{n,}$"。
    11.只能输入m~n位的数字:"^\\d{m,n}$"。
    12.只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。
    13.只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。
    14.只能输入有1~3位小数的正实数:"^[0-9]+(\.[0-9]{1,3})?$"。
    15.只能输入非零的正整数:"^\+?[1-9][0-9]*$"。
    16.只能输入非零的负整数:"^\-[1-9][]0-9"*$。
    17.只能输入长度为3的字符:"^.{3}$"。
    18.只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。
    19.只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。
    20.只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。
    21.验证是否含有^%&',;=?$\"等字符:"[^%&',;=?$\x22]+"。
    22.只能输入汉字:"^[\u4e00-\u9fa5]{0,}$"。
    23.验证URL:"^http://([\\w-]+\.)+[\\w-]+(/[\\w-./?%&=]*)?$"。
    24.验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"10"~"12"。
    25.验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"、"10"~"29"和“30”~“31”。
    26.获取日期正则表达式:\\d{4}[年|\-|\.]\\d{\1-\12}[月|\-|\.]\\d{\1-\31}日?
    评注:可用来匹配大多数年月日信息。
    27.匹配双字节字符(包括汉字在内):[^\x00-\xff]
    评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
    28.匹配空白行的正则表达式:\n\s*\r
    评注:可以用来删除空白行
    29.匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</>|<.*? />
    评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
    30.匹配首尾空白字符的正则表达式:^\s*|\s*$
    评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
    31.匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
    评注:网上流传的版本功能很有限,上面这个基本可以满足需求
    32.匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    评注:表单验证时很实用
    33.匹配腾讯QQ号:[1-9][0-9]\{4,\}
    评注:腾讯QQ号从10 000 开始
    34.匹配中国邮政编码:[1-9]\\d{5}(?!\d)
    评注:中国邮政编码为6位数字
    35.匹配ip地址:((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)。
     
    展开全文
  • 上一篇讲到,通过编译原理的方法(词法分析和语法分析)来判断字符串表示的算术表达式的合法性。这一篇,接着讲在算术表达式合法的情况下,对表达式进行求值。 问题:给定一个字符串,只包含 '+'、'-'、'*'、'/'...

    << 算术表达式的合法性判断与求值(上)

    上一篇讲到,通过编译原理的方法(词法分析和语法分析)来判断字符串表示的算术表达式的合法性。这一篇,接着讲在算术表达式合法的情况下,对表达式进行求值。

    问题:给定一个字符串,只包含 '+'、'-'、'*'、'/'、数字、小数点、'(' 、')'
    要求:(1) 判断该算术表达式是否合法; (2) 如果合法,计算该表达式的值。

    三、算术表达式的求值

    表达式的求值是栈应用的一个典型范例。我们一般通过后缀表达式(逆波兰式)进行求值,因为对后缀表达式求值比直接对中缀表达式求值简单很多。中缀表达式不仅依赖运算符的优先级,而且还要处理括号,而后缀表达式中已经考虑了运算符的优先级,且没有括号。

    所以,这里对表达式的求值分两个步骤进行:首先,把中缀表达式转换为后缀表达式,然后,对后缀表达式求值。

    1)中缀转后缀

    在把中缀转后缀的过程中,需要考虑操作符的优先级。根据《数据结构与算法分析》一书中的描述,我们需要利用一个(存放操作符)和一个输出字符串Output,从左到右读入中缀表达式:

    1. 如果字符是操作数,将它添加到 Output。
    2. 如果字符是操作符,从栈中弹出操作符,到 Output 中,直到遇到左括号 或 优先级较低的操作符(并不弹出)。然后把这个操作符 push 入栈。
    3. 如果字符是左括号,无理由入栈。
    4. 如果字符是右括号,从栈中弹出操作符,到 Output 中,直到遇到左括号。(左括号只弹出,不放入输出字符串)
    5. 中缀表达式读完以后,如果栈不为空,从栈中弹出所有操作符并添加到 Output 中。

    好了,下面直接上代码:

    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
    
    // 获取运算符的优先级
    int prior(char c)
    {
    	switch (c)
    	{
    		case '+':
    		case '-':
    			return 1;
    		case '*':
    		case '/':
    			return 2;
    		default:
    			return 0;
    	}
    }
    
    // 判断是否是运算符
    bool isOperator(char c)
    {
    	switch (c)
    	{
    		case '+':
    		case '-':
    		case '*':
    		case '/':
    			return true;
    		default:
    			return false;
    	}
    }
    
    // 中缀转后缀
    string getPostfix(const string& expr)
    {
    	string output;  // 输出
    	stack<char> s;  // 操作符栈
    	for(int i=0; i<expr.size(); ++i)
    	{
    		char c = expr[i];
    		if(isOperator(c))
    		{
    			while(!s.empty() && isOperator(s.top()) && prior(s.top())>=prior(c))
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.push(c);
    		}
    		else if(c == '(')
    		{
    			s.push(c);
    		}
    		else if(c == ')')
    		{
    			while(s.top() != '(')
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.pop();
    		}
    		else
    		{
    			output.push_back(c);
    		}
    	}
    	while (!s.empty())
    	{
    		output.push_back(s.top());
    		s.pop();
    	}
    	return output;
    }
    
    int main()
    {
    	string expr = "a+b*c+(d*e+f)*g";
    	string postfix = getPostfix(expr);
    	cout << expr << endl << postfix << endl;
    	return 0;
    }

    相信应该不需要我再解释什么了,请对照上面的规则看代码。

    2)后缀表达式求值

    得到了后缀表达式以后,对后缀表达式的求值就变得非常简单了。只需要使用一个栈,从左到右读入后缀表达式:

    1. 如果字符是操作数,把它压入堆栈。
    2. 如果字符是操作符,从栈中弹出两个操作数,执行相应的运算,然后把结果压入堆栈。(如果不能连续弹出两个操作数,说明表达式不正确)
    3. 当表达式扫描完以后,栈中存放的就是最后的计算结果。

    好了,话不多说,直接上代码:

    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
    
    int prior(char c)
    {
    	switch (c)
    	{
    		case '+':
    		case '-':
    			return 1;
    		case '*':
    		case '/':
    			return 2;
    		default:
    			return 0;
    	}
    }
    
    bool isOperator(char c)
    {
    	switch (c)
    	{
    		case '+':
    		case '-':
    		case '*':
    		case '/':
    			return true;
    		default:
    			return false;
    	}
    }
    
    string getPostfix(const string& expr)
    {
    	string output;  // 输出
    	stack<char> s;  // 操作符栈
    	for(int i=0; i<expr.size(); ++i)
    	{
    		char c = expr[i];
    		if(isOperator(c))
    		{
    			while(!s.empty() && isOperator(s.top()) && prior(s.top())>=prior(c))
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.push(c);
    		}
    		else if(c == '(')
    		{
    			s.push(c);
    		}
    		else if(c == ')')
    		{
    			while(s.top() != '(')
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.pop();
    		}
    		else
    		{
    			output.push_back(c);
    		}
    	}
    	while (!s.empty())
    	{
    		output.push_back(s.top());
    		s.pop();
    	}
    	return output;
    }
    
    // 从栈中连续弹出两个操作数
    void popTwoNumbers(stack<int>& s, int& first, int& second)
    {
    	first = s.top();
    	s.pop();
    	second = s.top();
    	s.pop();
    }
    
    // 计算后缀表达式的值
    int expCalculate(const string& postfix)
    {
    	int first,second;
    	stack<int> s;
    	for(int i=0; i<postfix.size(); ++i)
    	{
    		char c = postfix[i];
    		switch (c)
    		{
    		case '+':
    			popTwoNumbers(s, first, second);
    			s.push(second+first);
    			break;
    		case '-':
    			popTwoNumbers(s, first, second);
    			s.push(second-first);
    			break;
    		case '*':
    			popTwoNumbers(s, first, second);
    			s.push(second*first);
    			break;
    		case '/':
    			popTwoNumbers(s, first, second);
    			s.push(second/first);
    			break;
    		default:
    			s.push(c-'0');
    			break;
    		}
    	}
    	int result = s.top();
    	s.pop();
    	return result;
    }
    
    int main()
    {
    	string expr = "5+2*(6-3)-4/2";
    	string postfix = getPostfix(expr);
    	int result = expCalculate(postfix);
    	cout << "The result is: " << result << endl;
    	return 0;
    }

    注意,示例中的操作数都是单个的字符(0-9),但是通常的表达式不会是这种特殊情况,这就是我们需要对表达式进行词法解析的原因。

    四、解决问题

    好了,下面我们就结合上篇讲的词法分析对一个含有整数或小数的表达式进行求值。

    因为操作数不再是单个字符(个位数),我们需要对表达式进行词法解析。这里经过解析后,将(单词, 种别编码)对存入到一个vector<pair<string, int>>中,所以我们的中缀转后缀、后缀表达式求值都是对这个vector结构进行遍历。

    假设表达式已经判断为合法,求值的完整代码如下:

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <stack>
    #include <utility>
    using namespace std;
    
    int word_analysis(vector<pair<string, int>>& word, const string expr)
    {
    	for(int i=0; i<expr.length(); ++i)
    	{
    		// 如果是 + - * / ( )
    		if(expr[i] == '(' || expr[i] == ')' || expr[i] == '+' 
    			|| expr[i] == '-' || expr[i] == '*' || expr[i] == '/')
    		{
    			string tmp;
    			tmp.push_back(expr[i]);
    			switch (expr[i])
    			{
    			case '+':
    				word.push_back(make_pair(tmp, 1));
    				break;
    			case '-':
    				word.push_back(make_pair(tmp, 2));
    				break;
    			case '*':
    				word.push_back(make_pair(tmp, 3));
    				break;
    			case '/':
    				word.push_back(make_pair(tmp, 4));
    				break;
    			case '(':
    				word.push_back(make_pair(tmp, 6));
    				break;
    			case ')':
    				word.push_back(make_pair(tmp, 7));
    				break;
    			}
    		}
    		// 如果是数字开头
    		else if(expr[i]>='0' && expr[i]<='9')
    		{
    			string tmp;
    			while(expr[i]>='0' && expr[i]<='9')
    			{
    				tmp.push_back(expr[i]);
    				++i;
    			}
    			if(expr[i] == '.')
    			{
    				++i;
    				if(expr[i]>='0' && expr[i]<='9')
    				{
    					tmp.push_back('.');
    					while(expr[i]>='0' && expr[i]<='9')
    					{
    						tmp.push_back(expr[i]);
    						++i;
    					}
    				}
    				else  
    				{
    					return -1;  // .后面不是数字,词法错误
    				}
    			}
    			word.push_back(make_pair(tmp, 5));
    			--i;
    		}
    		// 如果以.开头
    		else  
    		{
    			return -1;  // 以.开头,词法错误
    		}
    	}
    	return 0;
    }
    
    // 获取运算符的优先级
    int prior(int sym)
    {
    	switch (sym)
    	{
    		case 1:
    		case 2:
    			return 1;
    		case 3:
    		case 4:
    			return 2;
    		default:
    			return 0;
    	}
    }
    
    // 通过 种别编码 判定是否是运算符
    bool isOperator(int sym)
    {
    	switch (sym)
    	{
    		case 1:
    		case 2:
    		case 3:
    		case 4:
    			return true;
    		default:
    			return false;
    	}
    }
    
    // 中缀转后缀
    vector<pair<string, int>> getPostfix(const vector<pair<string, int>>& expr)
    {
    	vector<pair<string, int>> output;  // 输出
    	stack<pair<string, int>> s;  // 操作符栈
    	for(int i=0; i<expr.size(); ++i)
    	{
    		pair<string, int> p = expr[i];
    		if(isOperator(p.second))
    		{
    			while(!s.empty() && isOperator(s.top().second) && prior(s.top().second)>=prior(p.second))
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.push(p);
    		}
    		else if(p.second == 6)
    		{
    			s.push(p);
    		}
    		else if(p.second == 7)
    		{
    			while(s.top().second != 6)
    			{
    				output.push_back(s.top());
    				s.pop();
    			}
    			s.pop();
    		}
    		else
    		{
    			output.push_back(p);
    		}
    	}
    	while (!s.empty())
    	{
    		output.push_back(s.top());
    		s.pop();
    	}
    	return output;
    }
    
    // 从栈中连续弹出两个操作数
    void popTwoNumbers(stack<double>& s, double& first, double& second)
    {
    	first = s.top();
    	s.pop();
    	second = s.top();
    	s.pop();
    }
    
    // 把string转换为double
    double stringToDouble(const string& str)
    {
    	double d;
    	stringstream ss;
    	ss << str;
    	ss >> d;
    	return d;
    }
    
    // 计算后缀表达式的值
    double expCalculate(const vector<pair<string, int>>& postfix)
    {
    	double first,second;
    	stack<double> s;
    	for(int i=0; i<postfix.size(); ++i)
    	{
    		pair<string,int> p = postfix[i];
    		switch (p.second)
    		{
    		case 1:
    			popTwoNumbers(s, first, second);
    			s.push(second+first);
    			break;
    		case 2:
    			popTwoNumbers(s, first, second);
    			s.push(second-first);
    			break;
    		case 3:
    			popTwoNumbers(s, first, second);
    			s.push(second*first);
    			break;
    		case 4:
    			popTwoNumbers(s, first, second);
    			s.push(second/first);
    			break;
    		default:
    			s.push(stringToDouble(p.first));
    			break;
    		}
    	}
    	double result = s.top();
    	s.pop();
    	return result;
    }
    
    int main()
    {
    	string expr = "(1.5+2.5)*2-0.5";
    	vector<pair<string, int>> word;
    	int err_num = word_analysis(word, expr);
    	if (-1 == err_num)
    		cout << "Word Error!" << endl;
    	else
    	{
    		double result = expCalculate(getPostfix(word));
    		cout << expr + " = " << result << endl;
    	}	
    	return 0;
    }

    为了防止精度的损失,不论是整数还是小数,在这里都通过stringToDouble()函数转为 double 浮点数。






    附:字符串转int/float/double类型

    方法一:atoi、atof

    在C语言的头文件 stdlib.h 里提供了两个函数,用于将字符串转换为整数或浮点数。函数原型分别为:

    int atoi(const char *nptr);          // 字符串转整数
    double atof(const char *nptr);       // 字符串转浮点数

    方法二:stringstream

    在C++里,可以利用 stringstream 方便的将 string 转换为 int、float、double:

    double stringToDouble(const string& str) {
    	double d; 
    	stringstream ss;
    	ss << str;    // 把字符串写入字符流
    	ss >> d;      // 输出到double
    	return d;
    }
    
    string doubleToString(const double& d) {
    	string str; 
    	stringstream ss;
    	ss << d;  
    	ss >> str;
    	return str;
    }

    通过 stringstream 将 string 转换为 int 或 float 与上面的方法是一样的,只需要改一下变量的类型就可以了。


    (全文完)














    展开全文
  • 正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 Regex regex = new Regex(@"[\u4e00-\u9fa5]"); string str = “48445helloWorld!” regex.IsMatch(str.ToString()) bai\u4e00”和“\u9fa5”是...
  • 那么onclick事件是不行的,因为一点击input那么onclick事件就执行,但是这时候还没上传内容,但是onchange事件是上传完成后才执行的事件以下方法就是判断是否是excel文件var File=document.getElem...
  • 判断颜色是否合法的正则表达式(详解)"^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$";意思是:以#开头,后面是数字和a-f的字符(大写或小写),这个值是6位或3位。要匹配一个3为是为了符合css颜色的简写规则:"#abc"=="#aabbcc...
  • 例如在登录界面里,我们通常都是要检验输入的用户名和密码不能为空才可以进行登录。 在这种场景下,可以直接可以在布局文件中使用Databinding直接对Edittext的数据进行检查,若其中有一个信息为空,则登录按钮禁用...
  • php用正则表达式判断手机号码的写法: 从文章中匹配出所有的手机号就可以:preg_match_all(); 如果要检查用户输入的手机号是否正确可这样来检查:preg_match(). 用正则匹配手机号码的时候, 我们先分析一下手机号码...
  • Java 三目运算符

    2021-02-12 10:14:56
    对于有些选择分支结构,可以使用简单的条件运算符来代替.如:引用if(amin=a;elsemin=b;可以用下面的条件运算符来处理min=(a其中"...以下是关于条件运算符的几点说明:(1) 通常情况下,表达式1是关系表达式或逻辑表达式,...
  • SpEL表达式

    2019-12-31 16:52:10
    Spring Expression Language(缩写为SpEL)是一种强大的表达式语言。在Spring产品组合中,它是表达式计算的基础。它支持在运行时查询和操作对象图,它可以与基于XML和基于注解的Spring配置还有bean定义一起使用。...
  • 查询表达式和条件表达式

    千次阅读 2019-09-15 16:20:31
    查询表达式 查询表达式可以作为过滤,分组,注解或者是聚合的一个值或者是计算。有很多内置表达式可以帮助你完成自己的查询。表达式可以组合,甚至是嵌套,来完成更加复杂的计算 内置表达式 说明 这些表达式...
  • 正则表达式

    千次阅读 2021-02-27 16:00:43
    正则表达式 - 匹配规则基本模式匹配一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内...
  • 日工资制通常适用于员工出勤率不足或节假日加班的情形。()面斜裂是由于上颌隆起与同侧的内侧鼻隆起未愈合所致。在常温下为液态生物碱的是: (2.0分)汽车排出的氮氧化物(NOx)有95%以上是二氧化氮。Romeo put the ____ ...
  • 判断汉字正则表达式更严谨方法!

    万次阅读 热门讨论 2015-07-20 14:22:41
    正如网上流传的,判断中文的正则表达式,绝大部分是这么写的(OC语言): NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"[\u4e00-\u9fa5]"]; /*判断是否为中文的正则表达式*/ if...
  • 逻辑表达式

    千次阅读 2021-07-25 02:37:41
    C语言编译系统在给出逻辑运算结果时,以数字1表示“真”,以数字0表示“假”,但在判断一个量是否为“真”时,以0表示“假”,以非0表示“真”。中文名逻辑表达式外文名logic expression学科数理科学类型数学术语...
  • 那么正则表达式通常有哪些使用场景呢? 比如为想要匹配的相应字符串集指定规则; 该字符串集可以是包含e-mail地址、Internet地址、电话号码,或是根据需求自定义的一些字符串集; 当然也可以去判断一个字符串集是否...
  • JavaScript语句 语句就是JavaScript指令,通过...如果再表达式的尾部附加一个分号就会形成一个表达式语句。JavaScript默认独立一行的表达式也是表达式语句,解析时自动补加分号。 表达式语句是最简单、最基本的语句...
  • php用正则表达式判断手机号码的写法:从文章中匹配出所有的手机号就可以preg_match_all(),如果要检查用户输入的手机号是否正确可这样来检查:preg_match(). 用正则匹配手机号码的时候, 我们先分析一下手机号码的规律: ...
  • 通常android有自己的sdk库判断web url是否为有效的url, Patterns.WEB_URL.matcher(str).matches()。 这个是对url进行通用的判断,最近根据产品需求,需要添加一些social media link,并验证这些link是否有效且...
  • 那么onclick事件是不行的,因为一点击input那么onclick事件就执行,但是这时候还没上传内容,但是onchange事件是上传完成后才执行的事件以下方法就是判断是否是excel文件var File=document.getElementById(“f...
  • 常量的命名通常为全部大写 在这里的100 这种像是魔术一样 不知道具体是什么的数 被称为魔法数(Magic Number) 因此 使用有意义的名称更容易使人理解 三、表达式表达式中 参与运算的数被称为算子 无论是变量还是...
  • EL表达式和JSTL标签库使用

    千次阅读 2017-08-06 21:18:44
    EL表达式 介绍: EL(Expression Language) 目的:为了使JSP写起来更加简单。  表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法。它是一种简单的语言,基于可用的...
  • Python 条件表达式

    千次阅读 2019-01-10 20:23:55
    在 Python 中,有一种特殊的表达式 -条件表达式(也被称为条件运算符,或者三元运算符),其语法规则如下:<expr1>if<...
  • 正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 不用过多介绍,大家对正则表达式应该不太陌生。即使没有用过,也一定听说过。 我们先看几个常见的正则表达式: 匹配 IP 地址 ((2[0-4]\d|25[0...
  • 如何在Scala中使用条件表达式

    万次阅读 2012-11-06 08:45:43
    条件表达式 Scala的if/else语法结构和Java或C++一样。不过,在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值。例如: if (x > 0) 1 else -1 上述表达式的值是1或−1,具体是哪一个取决于x的...
  • 正则表达式教程及常用正则表达式

    千次阅读 2016-12-07 01:22:52
    正则表达式教程、常用正则表达式以及正则表达式测试工具
  • 首先,我们先了解一下GUID的概念及正则表达式。 GUID,全局统一标识符。在Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。通用的GUID的结构如下typedef ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 215,487
精华内容 86,194
关键字:

判断表达式通常