Java自学者的第四篇学习笔记

写一写有关正则表达式的内容吧,这部分知识对于编程是很有帮助的。

语法(Grammer)定义了一类字符串。假设我们写了一个代表统一资源定位器(URL)的语法。该语法就代表了HTTP协议中合法的URL的集合。

语法中文字形式的字符串称为终结符(terminal)。之所以这样称它是因为其不能作进一步的扩展。我们通常以单引号标识这类字符串。

语法由一个被生成器(production)组成的类所描述,其中每一个生成器定义了一个非终结符(nonterminal)。一个语法的生成器有如下形式:

nonterminal ::= expression of terminals, nonterminals, and operators

一个语法具有一个唯一的非终结符称为根(root),它所包含的所有字符串都是从根生成的。

语法操作符

1. 闭包运算(Repetition),由*表示:

x ::= y*        // x matches zero or more y

2. 连接运算(Concatenation),仅由一个空格表示:

x ::= y z       // x matches y followed by z

3. 联合运算(Union),由|表示:

x ::= y | z     // x matches either y or z

4. 有或无(0 or 1 occurrence),由?表示:

x ::= y?       // an x is a y or is the empty string

5. 有(1 or more occurrences),由+表示:

x ::= y+       // an x is one or more y
               //    equivalent to  x ::= y y*

6. 有几个(exact number of occurrences, range of occurences):

x ::= y{3}     // an x is three y
               // equivalent to x ::= y y y 

x ::= y{1,3}   // an x is between one and three y
               // equivalent to x ::= y | y y | y y y

x ::= y{,4}    // an x is at most four y
               // equivalent to x ::=   | y | y y | y y y | y y y y
               //                     ^--- note the empty string here, so this can match zero y's

x ::= y{2,}    // an x is two or more y
               // equivalent to x ::= y y y*

7. 有哪些:

① character class

x ::= [aeiou]  // equivalent to  x ::= 'a' | 'e' | 'i' | 'o' | 'u'
x ::= [a-ckx-z]    // equivalent to  x ::= 'a' | 'b' | 'c' | 'k' | 'x' | 'y' | 'z'

② inverted character class

x ::= [^a-c]  // equivalent to  x ::= 'd' | 'e' | 'f' | ... | '0' | '1' | '2' | ... | '!' | '@'
              //                          | ... (all other possible characters)

语法中的递归以及语法分析树与形式语言理论中完全一致,在这里不再赘述。

正则表达式(Regular Expressions)可简称为regexes。由于进行了简化,regex相较于原先的语法可读性更差,例如:

// original grammer
url ::= 'http://' hostname (':' port)? '/' 
hostname ::= word '.' hostname | word '.' word
port ::= [0-9]+
word ::= [a-z]+

// regex
url ::= 'http://' ([a-z]+ '.')+ [a-z]+ (':' [0-9]+)? '/'

regex有一些更特殊的符号:

.   // matches any single character (but sometimes excluding newline, depending on the regex library)

\d  // matches any digit, same as [0-9]
\s  // matches any whitespace character, including space, tab, newline
\w  // matches any word character including underscore, same as [a-zA-Z_0-9]

反斜杠(\)可以理解为跳过(Escape),即跳过下一个字符,将其直接与文本匹配。

\.  \(  \)  \*  \+  \|  \[  \]  \\

注意,当你将上述带有反斜杠的符号复制到IDEA中时,前面会再加一个反斜杠,不要删除它!具体原因MIT Reading中是这样描述的(以\.为例):

We want to match a literal period ., so we have to first escape it as \. to protect it from being interpreted as the regex match-any-character operator, and then we have to further escape it as \\. to protect the backslash from being interpreted as a Java string escape character. The frequent necessity for double-backslash escapes makes regexes still less readable.

在Java中,你可以使用正则表达式对字符串进行操作。

将字符串s中所有连续的空格替换为单一空格:

String singleSpacedString = s.replaceAll(" +", " ");

匹配URL:

if (s.matches("http://([a-z]+\\.)+[a-z]+(:[0-9]+)?/")) {
    // then s is a url
}

提取如"2021-07-09"的日期:

String s = "2021-07-09";
Pattern regex = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher m = regex.matcher(s);
if (m.matches()) {
    String year = m.group("year");
    String month = m.group("month");
    String day = m.group("day");
    // Matcher.group(name) returns the part of s that matched (?<name>...)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值