使用Ruby re模块创建复杂的正则表达式

例如,考虑下面的匹配日期的正则表达式:


代码如下:

/\A((?:19|20)[0-9]{2})[\- \/.](0[1-9]|1[012])[\- \/.](0[1-9]|[12][0-9]|3[01])\z/

使用Re之后,正则表达式可以短小易读的表达式为基础,一步一步地构建出来,例如:


代码如下:

require 're'

include Re

delim                = re.any("- /.")
century_prefix       = re("19") | re("20")
under_ten            = re("0") + re.any("1-9")
ten_to_twelve        = re("1") + re.any("012")
ten_and_under_thirty = re.any("12") + re.any("0-9")
thirties             = re("3") + re.any("01")

year = (century_prefix + re.digit.repeat(2)).capture(:year)
month = (under_ten | ten_to_twelve).capture(:month)
day = (under_ten | ten_and_under_thirty | thirties).capture(:day)

date = (year + delim + month + delim + day).all

虽然代码量增加了,但是每个部分都很短小,也很容易验证。同时,捕获的部分可以通过相应的变量名访问:


代码如下:

result = date.match("2009-01-23")
result[:year]      # => "2009"
result[:month]     # => "01"
result[:day]       # => "23"

注意,用Re构建正则表达式会很慢,所以推荐创建正则表达式并复用。匹配的时候,性能和原生的正则表达式很接近。(额外的方法调用和创建Re::Result以返回匹配结果影响一点点性能。)如果你需要追求极致的性能,你仍然可以使用Re来构建正则表达式,然后抽取出原始的Ruby Regexp来匹配。这样的话,性能就和使用原生正则表达式一样了。

例如,构建匹配电话号码的正则表达式:


代码如下:

PHONE_RE = re.digit.repeat(3).capture(:area) +
               re("-") +
               re.digit.repeat(3).capture(:exchange) +
               re("-") +
               re.digit.repeat(4)).capture(:subscriber)

然后抽取出原始的正则对象,直接使用它来匹配:


代码如下:

PHONE_REGEXP = PHONE_RE.regexp

if PHONE_REGEXP =~ string
  # blah blah blah
end

(0)

相关推荐

  • 编写高质量的js之正确理解正则表达式回溯

    当一个正则表达式扫描目标字符串时,从左到右逐个扫描正则表达式的组成部分,在每个位置上测试能不能找到一个匹配.对于每一个量词和分支,都必须确定如何继续进行.如果是一个量词(如*.+?或者{2,}),那么正则表达式必须确定何时尝试匹配更多的字符:如果遇到分支(通过|操作符),那么正则表达式必须从这些选项中选择一个进行尝试. 当正则表达式做出这样的决定时,如果有必要,它会记住另一个选项,以备返回后使用.如果所选方案匹配成功,正则表达式将继续扫描正则表达式模板,如果其余部分匹配也成功了,那么匹配就结束了

  • 正则表达式创建方式的区别及编写简单的正则方式(js学习总结)

    在字面量方式中,我们//之间包起来的所有的内容都是元字符,有的具有特殊意义,大部分都是代表本身含义的普通的元字符 var name = 'wo'; var reg = /^\d+"+name+"\d+$/ 为了解决上述想在正则里面加上一个变量这样的需求,我们只能使用实例创建的方式了 var reg = new RegExp("^\\d+"+name+"\\d+$","g") 字面量方式和实例创建的方式在正则中的区别? 1.字面

  • VBS创建正则表达式对象的两种方法

    一直以来,我都是用 New RegExp 来创建正则表达式对象的: Set regex = New RegExp然而最新才发现 VBS 的正则表达式对象也可以这样创建: Set regex = CreateObject("VBScript.RegExp")貌似我看过的 VBScript 书籍没有一本介绍过这种写法,当然,书上没写的东西还有很多. 既然提到了正则表达式,那么就顺便说一下,VBS 的正则表达式对象是支持 MultiLine 模式的,对象有一个 MultiLine 属性.运行

  • js编写trim()函数及正则表达式的运用

    1.js中本身是没有trim函数的,不过你可以自己写一个 复制代码 代码如下: function trim(str) { var newStr = str.replace(/^\s*$/g,'') retrun newStr; } 2.去除字符串左右两端的空格,在vbscript里面可以轻松地使用 trim.ltrim 或 rtrim,但在js中却没有这3个内置方法,需要手工编写.下面的实现方法是用到了正则表达式,效率不错,并把这三个方法加入String对象的内置方法中去. 写成类的方法格式如下

  • 用正则表达式 动态创建/增加css style script 兼容IE firefox

    str 是表示通过ajax返回的XMLRequest /*动态加载css style*/ function loadStyle(str) { var regExp_src=/<style.*src\s*=\s*["'][^"']*["'].*>[^<>]*<\/style\s*>/gi; var matchArray_src=str.match(regExp_src); alert(matchArray_src[0]); if(matchA

  • 使用Ruby re模块创建复杂的正则表达式

    例如,考虑下面的匹配日期的正则表达式: 复制代码 代码如下: /\A((?:19|20)[0-9]{2})[\- \/.](0[1-9]|1[012])[\- \/.](0[1-9]|[12][0-9]|3[01])\z/ 使用Re之后,正则表达式可以短小易读的表达式为基础,一步一步地构建出来,例如: 复制代码 代码如下: require 're' include Re delim                = re.any("- /.")century_prefix      

  • python XlsxWriter模块创建aexcel表格的实例讲解

    安装使用pip install XlsxWriter来安装,Xlsxwriter用来创建excel表格,功能很强大,下面具体介绍: 1.简单使用excel的实例: #coding:utf-8 import xlsxwriter workbook = xlsxwriter.Workbook('d:\\suq\\test\\demo1.xlsx') #创建一个excel文件 worksheet = workbook.add_worksheet('TEST') #在文件中创建一个名为TEST的shee

  • Python基于win32ui模块创建弹出式菜单示例

    本文实例讲述了Python基于win32ui模块创建弹出式菜单.分享给大家供大家参考,具体如下: 一.代码: # -*- coding:utf-8 -*- #! python3 import win32ui import win32api from win32con import * from pywin.mfc import window class MyWnd(window.Wnd): def __init__ (self): window.Wnd.__init__(self,win32ui

  • node.js中ws模块创建服务端和客户端,网页WebSocket客户端

    首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require("ws"); // 启动基于websocket的服务器,监听我们的客户端接入进来. var server = new ws.Server({ host: "127.0.0.1", port: 6080, }); // 监听接入进来的客户端事件 function webs

  • Node.js fs模块(文件模块)创建、删除目录(文件)读取写入文件流的方法

    fs模块.js: /* 1. fs.stat 检测是文件还是目录(目录 文件是否存在) 2. fs.mkdir 创建目录 (创建之前先判断是否存在) 3. fs.writeFile 写入文件(文件不存在就创建,但不能创建目录) 4. fs.appendFile 写入追加文件 5.fs.readFile 读取文件 6.fs.readdir 读取目录 7.fs.rename 重命名 8. fs.rmdir 删除目录 9. fs.unlink 删除文件 */ var fs=require('fs');

  • node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文件等,就可以在浏览器中访问了 var express = require("express"); var path = require("path"); var app = express(); //目录 (当前目录下的www_root目录) app.use(expre

  • Python使用numpy模块创建数组操作示例

    本文实例讲述了Python使用numpy模块创建数组操作.分享给大家供大家参考,具体如下: 创建数组 创建ndarray 创建数组最简单的方法就是使用array函数.它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组. array函数创建数组 import numpy as np ndarray1 = np.array([1, 2, 3, 4]) ndarray2 = np.array(list('abcdefg')) ndarray3 = np.array([

  • node.js使用http模块创建服务器和客户端完整示例

    本文实例讲述了node.js使用http模块创建服务器和客户端.分享给大家供大家参考,具体如下: node.js中的 http 模块提供了创建服务器和客户端的方法,http 全称是超文本传输协议,基于 tcp 之上,属于应用层协议. 一.创建http服务器 const http = require('http'); //创建一个http服务器 let server = http.createServer(); //监听端口 server.listen(8888, '0.0.0.0'); //设置

  • node.js基于dgram数据报模块创建UDP服务器和客户端操作示例

    本文实例讲述了node.js基于dgram数据报模块创建UDP服务器和客户端操作.分享给大家供大家参考,具体如下: node.js中 dgram 模块提供了udp数据包的socket实现,可以方便的创建udp服务器和客户端. 一.创建UDP服务器和客户端 服务端: const dgram = require('dgram'); //创建upd套接字 //参数一表示套接字类型,'udp4' 或 'udp6' //参数二表示事件监听函数,'message' 事件监听器 let server = dg

  • node.js使用net模块创建服务器和客户端示例【基于TCP协议】

    本文实例讲述了node.js使用net模块创建服务器和客户端.分享给大家供大家参考,具体如下: node.js中net模块创建服务器和客户端 1.node.js中net模块创建服务器(net.createServer) // 将net模块 引入进来 var net = require("net"); // 创建一个net.Server用来监听,当连接进来的时候,就会调用我们的函数 // client_sock,就是我们的与客户端通讯建立连接配对的socket // client_soc

随机推荐