[java] 汇率换算器实现-插曲1-正则表达式(1)

 

[java] 汇率换算器实现-插曲1-正则表达式(1)

Table of Contents

2 前言

回顾一下, 在上篇文章种通过正则表达式的方式, 从网页中成功提取出了相应的汇率表的内容. 这篇文章就主要来介绍一下关于正则表达式的相关内容. 想要更为深入的了解, 请见Jeffrey的Mastering Regular Expressions .

3 什么是正则表达式

正则表达式作为计算机科学的一个概念, 可以使用单个字符串来描述, 匹配一系列符合某个句法规则的字符串. 正则表达式的基本语法可以在egrep的使用中了解, 更加复杂的用法就集成到了其他编程语言中, 如perl, python, java, php等.

4 正则表达式的初步运用–egrep

 

4.1 egrep支持的正则表达式的语法

 
符号 simple discription detail discription
. 匹配任何单个字符
[] 单字符集合 匹配任何列在里面的单个字符
[^…] 单字符的补集 匹配任何不在列表中的单个字符
{min, max} 匹配次数 至少匹配min次, 至多匹配max次
? 问号 {0, 1}
\(*\) 星号 {0,}
+ 加号 {1,}
^ 脱字号 匹配一行的开头
$ 美元号 匹配一行的结尾
\\< 单词边界 匹配一个单词的开始边界
\\> 单词边界 匹配一个单词的结尾边界
vertical line 选择 匹配其中一个表达式
() 括号 限制选择匹配的范围, 给匹配结果一个相应的标识
\1 应用 应用由()匹配的结果

4.2 举例说明

  1. 匹配一句话中连续重复的单词, 其间由空格分隔

    sentence in file.txt: Hello i am a a person, not a thing.
    exe: egrep -i '([a-zA-Z]+)( +\1){1,}' file.txt
    explane: -i 表示忽略大小写
  2. 匹配文中可能出现的输入错误的单词
    sentence in file.txt: Teh month
    exe: egrep -i '\<(hte|teh)\>' file.txt
  3. 匹配24小时制的时间
    exe: egrep '([01]?[0-9]|2[0-3]):[0-5][0-9]' tmp.txt
    

5 正则表达式更复杂的运用–perl

由于perl的使用不是本文的主题, 因此这里只是简略的说明下.

5.1 perl简单用法

 # filename: temps
$celsius = 20; # 变量赋值
while ($celsius <= 45) # 循环结构
{
if ($celsius != 30) # 选择结构
{
$fahrenheit = ($celsius * 9/5) + 32; # 计算
print "$celsius C is $fahrenheit F. \n"; # 输出结果
$celsius = $celsius + 5;
}
}
 perl temps

5.2 简单的字符匹配

 print "Enter a temperature in Celsius:\n";
$celsius = <STDIN>; # 用户输入
chomp($celsius); # 将结尾的换行符去掉
# 判断是否只有数字
if ($celsius =~ m/^[0-9]+$/) { # m means 尝试进行正则表达式匹配,
# =~ 说明正则表达式的对象是$reply
print "$celsius C\n";
} else {
print "not only digits\n";
}

又考虑到现实中, 温度的表示可以是负数, 小数, 因此, 正则表达式可以改为:

 m/^[-+]?[0-9]+(\.[0-9]+)?$/

5.3 获取匹配后的内容

那么如何获取匹配后的内容呢? 采用了()包围的方法, 如下:

 print "Enter a temperature in Celsius:\n";
$celsius = <STDIN>; # 用户输入
chomp($celsius); # 将结尾的换行符去掉
# 判断输入的格式是否为$number$space$unit
if ($celsius =~ m/^([-+]?[0-9]+(\.[0-9]+))? *([Cc])$/) { # m means 尝试进行正则表达式匹配,
# 如果, $number和$unit之间还有可能包括tab, 那么判断语句改为下式
# if ($celsius =~ m/^([-+]?[0-9]+(\.[0-9]+))?[ \t]*([Cc])$/) {
# =~ 说明正则表达式的对象是$reply
print "The number is $1, the unit is $3\n"; # group从左向右, 按照出现(的顺序进行编号
} else {
print "not matched\n";
}

上面的匹配行为中, 我们没有使用到$2, 那么有没有什么更好的方法将$2从group中排除掉, 量$3成为$2呢? 可以采用符号(?: ):

 $celsius =~ m/^([-+]?[0-9]+(?:\.[0-9]*)?)[ \t]*([Cc])$/

5.4 常用特殊字符, 匹配等

\t -> a tab character
\n -> a newline character
\r -> a carriage-return character
\s -> matches any "whitespace" character (space, tab, newline, formfeed, and such)
\S -> anything not \s
\w -> [a-zA-Z0-9_] (useful as in \w+, ostensibly to match a word)
\W -> anything not \w
\d -> [0-9]
\D -> anything not \d
\b -> 位置匹配, start of word and end of word
(?: ) -> the matched is not added to group
(?= ) -> 位置匹配, lookahead (toward the right), the subregex comes next
(?! ) -> 位置匹配, successful if can not match to the left
(?<= ) -> 位置匹配, lookbehind (toward the left), this position is after the subregex
(?<! ) -> 位置匹配, successful if can not match to the right
m/../i -> i means case-insensitive

5.5 匹配后进行替换

usage: s/regex/replacement/
for example: $var =~ s/\bJeff\b/Jeffrey/i; # 将Jeff单词替换为Jeffrey, 并且不区分大小写
for example: $var =~ s/\bJeff\b/Jeffrey/g; # g means将$var中出现的所有Jeff单词都替换为Jeffrey

下面给出一个问题, 如果某些导出的文件中的数字是很多位的, 如8.235897920, 这样并不方便读者进行阅读, 那么如何通过匹配以及替换的方式将多位小数转变位适当位数的小数呢, 如两位.

number regex: (\.\d\d)?\d*
implement: $price =~ s/(\.\d\d)?\d*/$1/g

5.6 一些例子

 

5.6.1 位置信息匹配

  • 仅匹配特殊字符的一部分, 如仅匹配Jeffrey中的Jeff, 而不匹配单纯的Jeff

    (?=Jeffrey)Jeff, (?=Jeffrey)用来确定确实存在Jeffrey, 并指定J前的位置.
    并且位置信息的匹配要在具体内容匹配之前, 也就是说regex: Jeff(?=Jeffrey), 不能实现上述的匹配
  • 将漏加的"'"添加上, 如本来应该是Jame's, 却写成了James, 用下面几种方式进行实现:
    s/\bJames\b/Jame's/g
    s/\bJeff(?=s\b)/Jeff'/g
    s/(?<=\bJame)(?=s\b)/'/g
  • 在一长整数中添加分隔的逗号, 使得数字更加易读. 如, 123456789, 改成1,2345,6789
    s/(?<=\d)(?=(\d{4})+\b)/,/g; # (?<=\d) 说明添加逗号的位置的左边必须有个数字
    # (?=(\d{4})+\b) 说明从单词的边界开始往左边数, 每隔4个数字, 添加一个逗号

5.6.2 文本文档转换为html格式

undef $/;
$text = <>; $text =~ s/&/&amp;/g; # make the basic html...
$text =~ s/</&lt;/g; # ...characters &, <, and >...
$text =~ s/>/&gt;/g; # ...HTML safe. # 下面使用了perl正则表达式中一个神奇的字符/m
# 在一般情况下^, 和 $表达的意思如下:
# ^: 匹配一个变量的第一个位置
# $: 匹配一个变量的最后一个位置
# 加了一个/m后, ^和$表示的意思将发生变化:
# ^: 匹配一行的第一个位置
# $: 匹配一行的最后一个位置
# 而$text变量的内容为: 一行内容+换行符+加下一行内容+...
# 因此想要将每一空行转变为<p>需用/m
$text =~ s/^\s*$/<p>/mg; # 将空行转变为<p> # 将email地址转变成links
# 这里使用了另一种书写方式s{regex}{replacement}gix
# 此时regex中可以使用空格, 注释语言使得regex更加的易读
# 结尾x的作用是忽略regex中多余的空格符,
# 值得注意的是, 它并不能忽略replacement中的空格项
$text =~ s{
\b
# Capture the address to $1
(
\w[-.\w]* # 用户名匹配, \w = [a-zA-Z0-9_]
\@ # 由于@在perl语言中有其他意思, 因此需要用转义字符进行转换
[-a-z0-9]+(\.[-a-z0-9]+)*\.(com|edu|info|others) # 域名, 此处others表示其他类似com, edu的内容
)
\b
}{<a href="mailto:$1">$1</a>}gix;
# Turn HTTP URLs into links ...
$text =~ s{
\b
(
http:// [-a-z0-9]+(\.[-a-z0-9]+)*\.(com|edu|others) \b # hostname
(
/ [-a-z0-9_:\@&?=+,.!/~*'%\$]* # 可选择的路径
(?<![.,?!]) # 匹配的最后位置, 不能在[.,?!]的后面
)?
)
}{<a href="$1">$1</a>}gix; print $text;

5.7 一些元字符的缩写

一些元字符的缩写

5.8 Excape Character, 转义字符

转义字符标志着一个字符序列中出现在它之后的后续几个字符采取一种替代解释.

5.9 字符类和字符类相似的结构

 

5.9.1 常见字符集合: [a-z] and [^a-z]

一般在8位的系统中, [^LMNOP]表示的意思为[\x00-KQ-\xFF], 但是字符系统为Unicode的时候, 最大值将会超出\xFF, 此时它表示的范围将包括出了LMNOP以外的所有字符(the tens of thousands).

5.9.2 dot字符

一般表示匹配除了换行符以外的所有字符. 以下情况需要注意:

  • 在某些的Unicode字符系统中, 如java regex package, dot一般不匹配unicode的行结尾字符
  • 在match mode, 它的含意会发生变化
  • 在基于POSIX标准的语言中, 并不匹配NUL, 尽管主流的脚本语言都允许在文本中出现NULLs, 并且能够匹配它们.

5.9.3 结合字符序列的Unicode: \X

\X支持匹配由多个Unicode编码组成的字符, 并且能够匹配换行符和其他Unicode行结尾符. 类似与".".

5.9.4 字符集缩写

\d: 数字[0-9], 在一些Unicode工具中为所有的Unicode数字
\D: [^\d]
\w: [0-9a-zA-Z_], 在某些工具中没有包括下划线. 如果, 支持unicode, \w通常表示为
所有的英文字母, 重要的例外, java.util.regex and PCRE, \w都表示[a-zA-Z0-9_]
\s: ascii-only系统中, [ \f\n\r\t\v]. 在unicode系统中, 有些时候还包括U+0085, \p{Z}

5.9.5 Unicode特性, 字符系统, 区块

很多unicode系统中, 经常通过"\p{quality}"来匹配包含某种特性的字符, 用"\P{quality}"来匹配不包含某种特性的字符.

Unicode的特性主要如下:

不同的字符系统的匹配, 比如匹配中文字符, \p{Han}, 区块与字符系统的匹配类似

5.10 位置信息匹配

 

5.10.1 一行或是字符串开始与结束的位置的匹配

5.10.2 上次匹配的后面的位置, 以及这次匹配开始的位置: \G

 

5.10.3 匹配字符边界

5.11 Grouping, Capturing, Conditionals, and Control

  • 利用()进行分组
  • 利用\1, \2获取不同组的信息
  • (?: )忽略当前组合,
  • 利用"|", 进行选择
  • 利用(?if then | else) 进行条件选择
  • 利用*, +, ?, {num, num}进行贪婪匹配
  • 利用*?, +?, ??, {num, num}?进行非贪婪匹配

Date: Fri May 9 20:03:42 CST 2014

Author: Zhong Xiewei

Org version 7.8.11 with Emacs version 24

Validate XHTML 1.0

[java] 汇率换算器实现-插曲1-正则表达式(1)的更多相关文章

  1. [java] jsoup使用简介-汇率换算器实现-插曲2

    [java] jsoup使用简介-汇率换算器实现-插曲2 // */ // ]]>   [java] jsoup使用简介-汇率换算器实现-插曲2 Table of Contents 1 系列文章 ...

  2. [java] 汇率换算器实现(3)

    [java] 汇率换算器实现(3) // */ // ]]>   [java] 汇率换算器实现(3) Table of Contents 1 系列文章地址 2 前言 3 提取简单表单信息 3.1 ...

  3. [java] 汇率换算器实现(2)

    [java] 汇率换算器实现(2) // */ // ]]> // */ // ]]>   [java] 汇率换算器实现(2) Table of Contents 1 系列文章地址 2 前 ...

  4. [java] 汇率换算器实现(1)

    [java] 汇率换算器实现(1) // */ // ]]>   [java] 汇率换算器实现(1) Table of Contents 1 问题描述 2 类设计 3 初步实现 3.1 建立项目 ...

  5. [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3

    [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 // */ // ]]>   [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 Table of C ...

  6. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  7. 【菜鸟学Python】案例一:汇率换算

    汇率换算V1.0 案例描述: 设计一个汇率换算器程序,其功能是将外币换算成人民币,或者相反 案例分析: 分析问题:分析问题的计算部分: 确定问题:将问题划分为输入.处理及输出部分: 设计算法:计算部分 ...

  8. 汇率换算自然语言理解功能JAVA DEMO

    >>>>>>>>>>>>>>>>>>>>>>>> 欢迎转 ...

  9. 万航单位换算器 V1.0 绿色版

    软件名称: 万航单位换算器软件语言: 简体中文授权方式: 免费软件运行环境: Win 32位/64位软件大小: 347KB图片预览: 软件简介:万航单位换算器是一个可以随意转换单位的绿色软件,这个软件 ...

随机推荐

  1. leetcode Insertion Sort List

    题目:Sort a linked list using insertion sort. 代码: /** * Definition for singly-linked list. * struct Li ...

  2. C# 的析构

    首先介绍下关于C#的GC垃圾回收器,有了这个垃圾回收器c#的开发人员可以不用像C++开发人员那样关心垃圾回收! 但是GC是把双刃剑,GC仅仅对于托管资源进行管理,对非托管资源却无能为力,并且C#的开发 ...

  3. GnuPG 1.4.15 发布,邮件加密工具

    GnuPG 1.4.15 改进包括: * Fixed possible infinite recursion in the compressed packet parser. [CVE-2013-44 ...

  4. Eclipse引入外部Jar在发布时没有自动带入,导致出现ClassNoFound错误

    今天换了一台电脑重新配置环境调试老程序的时候出现链接数据库错误java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver提示. ...

  5. ie8下使用knockoutjs遇到的一个模板异常

    ViewModel中有一个数组,代码大概如下: function ReportViewModel(){ var self = this; self.extendedProperties = ko.ob ...

  6. 图解js中常用的判断浏览器窗体、用户屏幕可视区域大小位置的方法

    有时我们需要获得浏览器窗口或屏幕的大小.窗口下拉框下拉的距离等数据,对应这些需求,js中提供了不少解决方法,只是数量稍多容易混淆它们各自的意义,下面咱们用图例来解释下12个常见对象属性的作用. 其中有 ...

  7. [.net 面向对象编程基础] (2) 关于面向对象编程

    [.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...

  8. 架构设计:前后端分离之Web前端架构设计

    在前面的文章里我谈到了前后端分离的一些看法,这个看法是从宏观的角度来思考的,没有具体的落地实现,今天我将延续上篇文章的主题,从纯前端的架构设计角度谈谈前后端分离的一种具体实现方案,该方案和我原来设想有 ...

  9. [编译] 1、第一个makefile简单例子

    前言 本篇用一个最简单的例子引入makefile,教你编写第一个makefile 正文 在Download/aa文件夹下有a.c和makefile文件 litao@litao:~/Downloads/ ...

  10. 《OOC》笔记(1)——C语言const、static和extern的用法

    <OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...