其他教程

其他教程

Products

当前位置:首页 > 其他教程 >

正则表达式匹配字符串问题

GG网络技术分享 2025-03-18 16:15 2


问题描述:

如下的字符串

Grance T\\\"om \"Bob Steave\" Lindy \"Su San\" \"Tom\'s Feare\" \"Array\\\" Creater\\\"\"

现在求一正则表达式能匹配出

Grance

T\"om

Bob Steave

Lindy

Su San

Tom\'s Feare

Array\" Creater\"

就是说能匹配上没一段话中的所有的子字符串
子字符串包括 Grance 这样的单词
用( \"\" )包裹起来的字符串 \"Bob Steave\"
包含转义符的字符串 T\"om
用( \"\" ) 包裹并包含转义符的字符串 Array\" Creater\"

网友观点:

单一的正则表达式不行,需要两个,第一个将你的引号分割的内容替换成 | 分割的,得到一个新的正则表达式
第二次用这个正则表达式和下面哪个比较。

楼主表述不是很清晰啊 可以把能变的部分用*或者× 表示整个你要的字符串

一个简单的方法,就是把引号中间的空格用其他字符比如#等替换,然后用空格做split分割得到数组,再把#用空格替换回来

用*或者× 表示整个字符串

将道理我连 var s = 后面的都不会写,是 \\\\\" 还是 \\\\\"

https://www.sogou.com/link?url=DOb0bgH2eKh1ibpaMGjuy_uPWQQzYciaxdiziXqK0vJRa6NQaxCrEoIlNwnFi_HrFsCpl722Ta8.

     public static List getContentArray(String content){

List<String> contentList = new ArrayList<String>();

String contentItem=\\\"\\\";

boolean hasQuote = false;

for(int i = 0; i<content.length() ;i++){

char item = content.charAt(i);

if(item == \'\\\"\'){

if(hasQuote){ // 如果当前引号前面有引号

hasQuote = false;

if(!contentItem.equals(\\\"\\\")){

contentList.add(contentItem);

contentItem = \\\"\\\";

}

}else{

hasQuote = true;

}

}else if(item == \'\\\\\'){

i++;

contentItem += content.charAt(i);

}else if(item == \' \'){

if(hasQuote){

contentItem += item;

}else{

if(!contentItem.equals(\\\"\\\")){

contentList.add(contentItem);

contentItem = \\\"\\\";

}

}

}else{

contentItem += item;

}

}

return contentList;

}

字符串之正则表达式

推荐一个github程序员资料仓库:

程序员免费资料仓

前言:

授人以鱼不如授人以渔,大家在编程的时候总会遇到要查找某些复杂规则的字符串,例如在 linux 系统中,需要对多个文件里的某段代码进行替换,你是不是还在每个文件打开逐一目标替换?如果你也有这样的困惑那么正则表达式就是你必须会的技能。

1、什么是正则表达式

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个 “规则字符串” ,这个 “规则字符串” 用来表达对字符串的一种过滤逻辑。换句话说,正则表达式就是记录文本规则的代码。

很可能你使用过 Windows 下用于文件查找的通配符(wildcard),也就是 * 和 ?。如果你想查找某个目录下的所有的 pdf 文档的话,可以直接搜索 *.pdf,如下:

在这里,* 会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求。当然,代价就是更复杂,比如你可以编写一个正则表达式,用来查找所有以 0 开头,后面跟着 2-3 个数字,然后是一个连字号 “-” ,最后是 7 或 8 位数字的字符串(像 011-12345678 或 0856-7654321)。

2、入门

学习正则表达式的最好方法是从例子开始。

  • 假如你在一篇英文期刊里查找 me,你可以使用正则表达式 me。

这几乎是最简单的正则表达式了,它可以精确匹配这样的字符串:由两个字符组成,前一个字符是 m, 后一个是 e。通常,处理正则表达式的工具会提供一个忽略大小写的选项,如果选中了这个选项,它可以匹配 me, ME, Me, mE 这四种情况中的任意一种。

不幸的是,很多单词里包含 hi 这两个连续的字符,比如 me, mean, measure等等。用 me 来查找的话,这里边的 me 也会被找出来。如果要精确地查找 me 这个单词的话,我们应该使用 \\bme\\b。

\\b 是正则表达式规定的一个特殊代码(有些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是 \\b 并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。

  • 假如你要找的是 me 后面不远处跟着一个 james,你应该用 \\bme\\b.*\\bjames\\b。

这里 . 是另一个元字符,匹配除了换行符以外的任意字符。* 同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定 * 前边的内容可以连续重复使用任意次以使整个表达式得到匹配。

因此 .* 连在一起就意味着任意数量的不包含换行的字符。现在\\bme\\b.*\\bjames\\b的意思就很明显了:先是一个单词 me 然后是任意个任意字符(但不能是换行),最后是 james 这个单词。

3、元字符

正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,要想真正的用好正则表达式,正确的理解元字符是最重要的事情。下表列出了常用的元字符

4、字符转义

如果想查找元字符本身的话,比如查找 . ,或者 * ,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时就得使用 \\ 来取消这些字符的特殊意义。因此,应该使用 . 和 *。当然,要查找 \\ 本身,也得用 \\。

例如:mayday\\.net 匹配 http://mayday.net ,C:\\\\Windows匹配C:\\Windows。

5、重复

已经看过了前面的 * , + 几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码:

6、字符类

要想查找数字、字母、数字、空白已经很简单,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元音字母 a,e,i,o,u ),应该怎么办?

很简单,你只需要在方括号里列出它们就行了,像 [aeiou] 就匹配任何一个英文元音字母, [.?!] 匹配标点符号( . 或 ? 或 !)。

我们也可以轻松地指定一个字符范围,像 [0-9] 代表的含意与 \\d 就是完全一致的:一位数字;同理 [a-z0-9A-Z_] 也完全等同于 \\w (如果只考虑英文的话)。

下面是一个更复杂的表达式:\\(?0\\d{2}[) -]?\\d{8}。

这个表达式可以匹配几种格式的电话号码,像 011-22884499 ,或 0845652452 等。我们对它进行一些分析吧:首先是一个转义字符 (,它能出现 0 次或 1 次 (?),然后是一个 0,后面跟着 2 个数字 (\\d{2}),然后是)或-或空格中的一个,它出现 1 次或不出现(?),最后是 8 个数字(\\d{8})。

7、反义

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义

例子:

\\S+ 匹配不包含空白符的字符串。 <a[^>]+> 匹配用尖括号括起来的以 a 开头的字符串

8、分组

我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?可以用小括号来指定子表达式(也叫做分组),然后就可以指定这个子表达式的重复次数了,也可以对子表达式进行其它一些操作。

(\\d{1,3}\\.){3}\\d{1,3} 是一个简单的 IP 地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\\d{1,3} 匹配 1 到 3 位的数字,(\\d{1,3}\\.){3} 匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复 3 次,最后再加上一个一到三位的数字(\\d{1,3})。

可是也将匹配256.300.777.888这种不可能存在的 IP 地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的 IP 地址:((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)。

理解这个表达式的关键是理解2[0-4]\\d|25[0-5]|[01]?\\d\\d?,这里就不细说了,大家应该能分析得出来它的意义。

9、贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是匹配尽可能多的字符。以这个表达式为例: b.*c ,它将会匹配最长的以 b 开始,以 c 结束的字符串。如果用它来搜索 babac 的话,它会匹配整个字符串 babac 。这被称为贪婪匹配。

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

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

10、处理选项

上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是 .Net 中常用的正则表达式选项:

一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?

答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。

11、提示

正则表达式内容还有很多,笔者这里只列举常用部分,读者若想进一步学习,可在微软专业正则表达式学习网站学习:

https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expressions?redirectedfrom=MSDN

标签:

提交需求或反馈

Demand feedback