前几天碰着一个需求,输入的是
<user> <user> <name>a</name> </user> <user> <name>a</name> </user> </user> <password>123</password>
要求拿到
<user> <user> <name>a</name> </user> <user> <name>a</name> </user> </user>
也就是去掉最后一个</user>后头的字符串。
要领有许多,我首先想到的是用正则匹配去掉</user>后头的字符串。
最后写出来的表达式是(?<=</user>)(?![\w\W]*</user>)[\w\W]+。
首先用(?<=</user>)匹配所有前面是</user>的位置,如图,总共有三个位置。
这里我们正则表达式(?<=</user>)的意思就是匹配的位置之前的字符串是</user>,也就是我们匹配到的位置在</user>之后。
这里用到了正则表达式语法中的断言,有的书上也称该语法为预查可能环顾,都是一样的用法。有如下语法:
(?=pattern) 零宽正向先行断言 (?!pattern) 零宽负向先行断言 (?<=pattern) 零宽正向后行断言 (?<!pattern) 零宽负向后行断言
这里用到的是(?<=pattern),零宽暗示它匹配的是在字符串中的位置,如同^匹配字符串串首,$匹配字符串串尾。正向代表它必需满意pattern。后行代表它匹配的位置在pattern之后。
其次,再这三个位置长举办筛选,可以或许看出这三个位置的区别是后头是否有</user>,假如没有的话那么它就是最后一个</user>后头的位置。在之前的表达式后头添上(?![\w\W]*?</user>)此时表达式变为(?<=</user>)(?![\w\W]*?</user>)。
可以或许看到获得了最后一个匹配功效。
这里的正则表达式(?!pattern) 是零宽负向先行断言,也就是它会往后匹配pattern,匹配到的位置在pattern之前,而且匹配到的字符串必需不满意pattern。
(?![\w\W]*?</user>)的意思是在匹配到的位置后头必需不是[\w\W]*?</user>,\w匹配的是[a-zA-Z0-9_]即匹配字母数字和下划线,而\W匹配的是[^a-zA-Z0-9_]即不是字母数字也不是下划线的字符,同时匹配这两个就相当于匹配任意字符。[\w\W]后头的*代表匹配0-任意多次,后头的?代表懒惰模式,即只要满意条件就当即返回。
最后,在之前的正则表达式后头加上[\w\W]+贪婪匹配即尽大概多的匹配该位置后头的字符串。最终的正则表达式是(?<=</user>)(?![\w\W]*?</user>)[\w\W]*
最后的最后用四张图简朴地描写四种断言的差异之处。
这里输入的字符串都是123456。
(?=3),它匹配的位置是后头的字符为3的位置。
(?<=3),它匹配的位置是前面的字符为3的位置。
(?!3)匹配的位置是后头的字符不为3的位置,可以看到箭头所指的处所没有被匹配到,其他位置都被匹配到了。
(?<!3)匹配的位置是前面的字符不为3的位置,可以看到箭头所指的处所没有被匹配到,其他位置都被匹配到了。
总结
到此这篇关于如何利用正则匹配最后一个字符串详解的文章就先容到这了,更多相关正则匹配最后一个字符串内容请搜索剧本之家以前的文章或继承欣赏下面的相关文章但愿各人今后多多支持剧本之家!
您大概感乐趣的文章: