可粗略估计一下,除了偶尔用Linux的外,其他Linu x用户都会遇到正则表达式。正则表达式是个极端强大工具,而且在字符串模式-匹配和字符串模式-替换方面富有d性。在Unix世界里,正则表达式几乎没有什么限制,可肯定的是,它应用非常之广泛。
正则表达式的引擎已被许多普通的Unix工具所实现,包括grep,awk,vi和Emacs等。此外,许多使用比较广泛的脚本语言也支持正则表达式,比如Python,Tcl,JavaScript,以及最著名的Perl。
我很早以前就是个Perl方面的黑客,如果你和我一样话,你也会非常依赖你手边的这些强大的text-munging工具。近几年来,像其他程序开发者一样,我也越来越关注Java的开发。
Java作为一种开发语言,有许多值得推荐的地方,但是它一直以来没有自带对正则表达式的支持。直到最近,借助于第三方的类库,Java开始支持正则表达式,但这些第三方的类库都不一致、兼容性差,而且维护代码起来很糟糕。这个缺点,对我选择Java作为首要的开发工具来说,一直是个巨大的顾虑之处。
你可以想象,当我知道Sun的Java JDK 140版本包含了javautilregex(一个完全开放、自带的正则表达式包)时,是多么的高兴!很搞笑的说,我花好些时间去挖掘这个被隐藏起来的宝石。我非常惊奇的是,Java这样的一个很大改进(自带了javautilregex包)为什么不多公开一点呢!
最近,Java双脚都跳进了正则表达式的世界。javautilregex包在支持正则表达也有它的过人之处,另外Java也提供详细的相关说明文档。使得朦朦胧胧的regex神秘景象也慢慢被拨开。有一些正则表达式的构成(可能最显著的是,在于糅合了字符类库)在Perl都找不到。
在regex包中,包括了两个类,Pattern(模式类)和Matcher(匹配器类)。Pattern类是用来表达和陈述所要搜索模式的对象,Matcher类是真正影响搜索的对象。另加一个新的例外类,PatternSyntaxException,当遇到不合法的搜索模式时,会抛出例外。
即使对正则表达式很熟悉,你会发现,通过java使用正则表达式也相当简单。要说明的一点是,对那些被Perl的单行匹配所宠坏的Perl狂热爱好者来说,在使用java的regex包进行替换 *** 作时,会比他们所以前常用的方法费事些。
本文的局限之处,它不是一篇正则表达式用法的完全教程。如果读者要对正则表达进一步了解的话,推荐阅读Jeffrey Frieldl的Mastering Regular Expressions,该书由O’Reilly出版社出版。我下面就举一些例子来教读者如何使用正则表达式,以及如何更简单地去使用它。
设计一个简单的表达式来匹配任何电话号码数字可能是比较复杂的事情,原因在于电话号码格式有很多种情况。所有必须选择一个比较有效的模式。比如:(212) 555-1212, 212-555-1212和212 555 1212,某些人会认为它们都是等价的。
首先让我们构成一个正则表达式。为简单起见,先构成一个正则表达式来识别下面格式的电话号码数字:(nnn)nnn-nnnn。
第一步,创建一个pattern对象来匹配上面的子字符串。一旦程序运行后,如果需要的话,可以让这个对象一般化。匹配上面格式的正则表达可以这样构成:(\d{3})\s\d{3}-\d{4},其中\d单字符类型用来匹配从0到9的任何数字,另外{3}重复符号,是个简便的记号,用来表示有3个连续的数字位,也等效于(\d\d\d)。\s也另外一个比较有用的单字符类型,用来匹配空格,比如Space键,tab键和换行符。
是不是很简单但是,如果把这个正则表达式的模式用在java程序中,还要做两件事。对java的解释器来说,在反斜线字符(\)前的字符有特殊的含义。在java中,与regex有关的包,并不都能理解和识别反斜线字符(\),尽管可以试试看。但为避免这一点,即为了让反斜线字符(\)在模式对象中被完全地传递,应该用双反斜线字符(\)。此外圆括号在正则表达中两层含义,如果想让它解释为字面上意思(即圆括号),也需要在它前面用双反斜线字符(\)。也就是像下面的一样:
\\(\\d{3}\\)\\s\\d{3}-\\d{4}
现在介绍怎样在java代码中实现刚才所讲的正则表达式。要记住的事,在用正则表达式的包时,在你所定义的类前需要包含该包,也就是这样的一行:
import javautilregex;
下面的一段代码实现的功能是,从一个文本文件逐行读入,并逐行搜索电话号码数字,一旦找到所匹配的,然后输出在控制台。
BufferedReader in;
Pattern pattern = Patterncompile("\\(\\d{3}\\)\\s\\d{3}-\\d{4}");
in = new BufferedReader(new FileReader("phone"));
String s;
while ((s = inreadLine()) != null)
{
Matcher matcher = patternmatcher(s);
if (matcherfind())
{
Systemoutprintln(matchergroup());
}
}
inclose();
对那些熟悉用Python或Javascript来实现正则表达式的人来说,这段代码很平常。在Python和Javascript这些语言中,或者其他的语言,这些正则表达式一旦明确地编译过后,你想用到哪里都可以。与Perl的单步匹配相比,看起来多多做了些工作,但这并不很费事。
find()方法,就像你所想象的,用来搜索与正则表达式相匹配的任何目标字符串,group()方法,用来返回包含了所匹配文本的字符串。应注意的是,上面的代码,仅用在每行只能含有一个匹配的电话号码数字字符串时。可以肯定的说,java的正则表达式包能用在一行含有多个匹配目标时的搜索。本文的原意在于举一些简单的例子来激起读者进一步去学习java自带的正则表达式包,所以对此就没有进行深入的探讨。
这相当漂亮吧! 但是很遗憾的是,这仅是个电话号码匹配器。很明显,还有两点可以改进。如果在电话号码的开头,即区位号和本地号码之间可能会有空格。我们也可匹配这些情况,则通过在正则表达式中加入\s来实现,其中元字符表示在模式可能有0或1个空格符。
第二点是,在本地号码位的前三位和后四位数字间有可能是空格符,而不是连字号,更有胜者,或根本就没有分隔符,就是7位数字连在一起。对这几种情况,我们可以用(-|)来解决。这个结构的正则表达式就是转换器,它能匹配上面所说的几种情况。在()能含有管道符|时,它能匹配是否含有空格符或连字符,而尾部的元字符表示是否根本没有分隔符的情况。
最后,区位号也可能没有包含在圆括号内,对此可以简单地在圆括号后附上元字符,但这不是一个很好的解决方法。因为它也包含了不配对的圆括号,比如"(555" 或 "555)"。相反,我们可以通过另一种转换器来强迫让电话号码是否带有有圆括号:(\(\d{3}\)|\d{3})。如果我们把上面代码中的正则表达式用这些改进后的来替换的话,上面的代码就成了一个非常有用的电话号码数字匹配器:
Pattern pattern =
Patterncompile("(\\(\\d{3}\\)|\\d{3})\\s\\d{3}(-|)\\d{4}");
可以确定的是,你可以自己试着进一步改进上面的代码。
现在看看第二个例子,它是从Friedl的中改编过来的。其功能是用来检查文本文件中是否有重复的单词,这在印刷排版中会经常遇到,同样也是个语法检查器的问题。
匹配单词,像其他的一样,也可以通过好几种的正则表达式来完成。可能最直接的是\b\w+\b,其优点在于只需用少量的regex元字符。其中\w元字符用来匹配从字母a到u的任何字符。+元字符表示匹配匹配一次或多次字符,\b元字符是用来说明匹配单词的边界,它可以是空格或任何一种不同的标点符号(包括逗号,句号等)。
现在,我们怎样来检查一个给定的单词是否被重复了三次为完成这个任务,需充分利用正则表达式中的所熟知的向后扫描。如前面提到的,圆括号在正则表达式中有几种不同的用法,一个就是能提供组合类型,组合类型用来保存所匹配的结果或部分匹配的结果(以便后面能用到),即使遇到有相同的模式。在同样的正则表达中,可能(也通常期望)不止有一个组合类型。在第n个组合类型中匹配结果可以通过向后扫描来获取到。向后扫描使得搜索重复的单词非常简单:\b(\w+)\s+\1\b。
圆括号形成了一个组合类型,在这个正则表示中它是第一组合类型(也是仅有的一个)。向后扫描\1,指的是任何被\w+所匹配的单词。我们的正则表达式因此能匹配这样的单词,它有一个或多个空格符,后面还跟有一个与此相同的单词。注意的是,尾部的定位类型(\b)必不可少,它可以防止发生错误。如果我们想匹配"Paris in the the spring",而不是匹配"Java's regex package is the theme of this article"。根据java现在的格式,则上面的正则表达式就是:Pattern pattern =Patterncompile("\\b(\\w+)\\s+\\1\\b");
最后进一步的修改是让我们的匹配器对大小写敏感。比如,下面的情况:"The the theme of this article is the Java's regex package",这一点在regex中能非常简单地实现,即通过使用在Pattern类中预定义的静态标志CASE_INSENSITIVE :
Pattern pattern =Patterncompile("\\b(\\w+)\\s+\\1\\b",
PatternCASE_INSENSITIVE);
有关正则表达式的话题是非常丰富,而且复杂的,用Java来实现也非常广泛,则需要对regex包进行的彻底研究,我们在这里所讲的只是冰山一角。即使你对正则表达式比较陌生,使用regex包后会很快发现它强大功能和可伸缩性。如果你是个来自Perl或其他语言王国的老练的正则表达式的黑客,使用过regex包后,你将会安心地投入到java的世界,而放弃其他的工具,并把java的regex包看成是手边必备的利器。正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
例如:
runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。
runoob,可以匹配 runob、runoob、runoooooob 等, 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。
colour 可以匹配 color 或者 colour, 问号代表前面的字符最多只可以出现一次(0次、或1次)。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。就拿你所给的“12345678”为例,我个人认为有两种方法:
1 String str = "12345678";
String str2 = strsubstring(4); //截取从第四个字符开始的子字符串
然后对str2应用正则表达式进行匹配
2 直接用正则表达式:
首先注意句点在正则表达式中的含义:
匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[\n]' 的模式。
由于是六位数字,而要从第四位开始匹配,前面三位用 代替,表示任意字符
即 {3}\d\d{2}
表示字符串第四、五个必须为数字,前面3个可以为任意除换行符以外的单个字符,最后两个单字符也为除换行符以外的单字符。
而如果是在MySQL或Oracle的SQL中,正则表达式应该是:
_ _ _\d\d_ _
短下划线与Java、JS、PHP中支持的正则表达式中的句点 意义相同,表示任意单个字符,上面的短下划线是连续的,为了便于阅读所以将其用空格分开,实际上是三个连续的短下划线。但SQL中匹配正则表达式用的是LIKE语法,比如
SELECT FROM people WHERE name LIKE '_ _ abc';
从people表中选择这样的行:这些行的name列值的第三个字符为a,第四个字符为b,第五个字符为c。
PS:
@tpaxatb,我不知道你是真傻还是装傻。为了得分你诬蔑我倒无所谓,误人子弟就不好了。
1 strsubstring(4)应该是第5个字符
你自己搞清楚,这个是得到第五个字符,还是得到从第五个字符开始的子字符串?基础不好不是你的错,基础不好还乱对别人指手画脚就是你的错了。估计你是培训机构出来的吧!真他妈少见啊!
2[\n]只代表点()和回车,不是点可以匹配包括 '\n' 在内的任何字符的意思
看清楚我说的是“匹配除 "\n" 之外的任何单个字符”,看清楚再发言好不好?这个就是提取整数或者小数的问题。
下面的代码复制,稍微调整就能满足你的要求
调用子程序 提取数值 时,参数 文本 就给你图中蓝色部分的文本
用 “输出数据”分割整体文本,取前面的部分
版本 2
支持库 RegEx
子程序 提取数值
参数 文本, 文本型
局部变量 正则, 正则表达式
局部变量 结果, 搜索结果, , "0"
局部变量 a, 整数型
正则创建 (“:(\d+(\\d+))”, )
结果 = 正则搜索全部 (文本)
计次循环首 (取数组成员数 (结果), a)
加入成员 (取得到的数据, 结果 [a]取子匹配文本 (文本, 1, ))
计次循环尾 ()RegexReplace的基本用法
2012-08-08 18:39阅读:8,313
Regex构造函数
Regex(string pattern)
Regex(string pattern,RegexOptions options)
参数说明
pattern:要匹配的正则表达式模式
options:指定是否要编译,忽略大小写等等
RegexReplace方法
-C#
RegexReplace(string input,string replacement)
RegexReplace(string input,string replacement,int count)
RegexReplace(string input,string replacement,int count,int startat)
RegexReplace(string input,MatchEvaluator evaluator)
RegexReplace(string input,MatchEvaluator evaluator,int count)
RegexReplace(string input,MatchEvaluator evaluator,int count,int startat)
参数说明
input:要修改的字符串
replacement:替换字符串
count:进行替换的最大次数
startat:输入字符串开始搜索的位置
evaluator:在每一步计算替换的MatchEvaluator。(MatchEvaluator的使用举例)就是一个函数代理,参数为Match类型,匹配的数据。
同样的内容只替换一次举例:
Regex Reg = new Regex('oldWords');
Content = RegReplace(Content, NewWords, 1);//oldWords只替换一次
提高生产力的数据和系统可视化工具
随着文件、数据集和配置的增长,导航它们变得越来越困难。然而,有许多工具可以帮助你在处理大型 JSON 和 YAML 文件、复杂的正则表达式、令人困惑的 SQL 数据库关系、复杂的开发环境等等时提高工作效率。
JSON 是一种对计算机很好但对人不友好的格式。即使是相对较小的 JSON 对象也可能很难读取和遍历,但有一个工具可以提供帮助!
JSON Visio 是一个从 JSON 对象生成图表的工具。这些图表比文本格式更容易导航,并且更方便,该工具还允许你搜索节点。此外,生成的图表也可以作为图像下载。
你可以在>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)