正则表达式之环视(Lookaround)[转]

1       环视基础

环视只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果,是零宽度的。环视匹配的最终结果就是一个位置。

环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功。

环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视。顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件。

表达式

说明

(?<=Expression)

逆序肯定环视,表示所在位置左侧能够匹配Expression

(?<!Expression)

逆序否定环视,表示所在位置左侧不能匹配Expression

(?=Expression)

顺序肯定环视,表示所在位置右侧能够匹配Expression

(?!Expression)

顺序否定环视,表示所在位置右侧不能匹配Expression

  阅读全文 >>

Scala 的学习笔记系列(持续更新中)

最近学习 Scala,因它是灵活的函数式编程,还有就是能为 PlayFramework 2.0 服务,看的是 《Programming in Scala》 那本书,并记下自己认为值得记录的东西,列举

  1. Scala 用元组/列表类型实现多返回值的函数
  2. Scala 无参数方法和统一访问原则
  3. Scala 的 apply 和 update 方法的应用
  4. Scala 特质(trait) 的 super 方法调用是动态绑定的 
  5. Scala 的 yield 例子 (for 循环和 yield 的例子)
  6. Scala 中 ensuring 方法的使用说明
  7. Scala 2.10.0 新特性之使用隐式类进行类型隐式转换
  8. Scala 2.10.0 新特性之动态属性、方法
  9. Scala 2.10.0 新特性之字符串插值
  10. 使用 sbt 的 np 插件自动创建目录结构和 build.sbt 文件

关于 PlayFramework 2.0 的应用请参考我的另一个系列:

Play 2.0 中文资料--翻译附注解(持续更新中)

Play 2.0 中文资料--翻译附注解(持续更新中)

最近在研究 PlayFramework 2.0,主要关注在使用 Scala 来写 Play 2.0 的应用,下面是从官方文档进行的翻译,并加入了大量的自己的理解与备注( Unmi 注: 起头的蓝色文字)

  1. Play 2.0 中文资料 - 开篇
  2. Play 2.0 中文资料 - 安装 
  3. Play 2.0 中文资料 - 创建一个新的应用 
  4. Play 2.0 中文资料 - 剖析 Play 2.0 应用 
  5. Play 2.0 中文资料 - 使用 Play 2.0 控制台 
  6. Play 2.0 中文资料 - HTTP 编程 
  7. Play 2.0 中文资料 - 搭建你偏爱的 IDE 
  8. Play 2.0 中文资料 - Action, Controller 和 Result 
  9. Play 2.0 中文资料 - HTTP 路由 
  10. Play 2.0 中文资料 - 操控 Result  阅读全文 >>

简单实现 Java 的 Tuple 元组数据类型

元组类型,即 Tuple 常在脚本语言中出现,例如 Scala 的 ("Unmi", "fantasia@sina.com", "blahbla")。元组可认为是象数组一样的容器,它的目的是让你方便构造和引用,例如 Pair 可认为是一个只能存两个元素的元组,像是个 Map; 真正的元组应该是可以任意多个元素的容器,绕来绕去,它还是数组,或列表,所以我们实现上还是要借助于数组或是列表。

先看 Scala 中什么是元组:

Scala 中访问从 1 开始,用 ._1 方式来访问其中的元素。

参照于此,写出一个 Java 版本的 Tuple,为增长你的键盘的使用寿命,我们把方法名也缩短了,例如 make 缩写为 mk,引用元素的方法名为 _,仍然保持 Java 的习惯,索引从 0 开始: 阅读全文 >>

Java 里把 InputStream 转换成 String 的几种方法

我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量。

未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取。其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google  Guava 库的 CharStreams。到了 JDK7,若要从文件中直接得到字符串还能用 java.nio.file.Files#readAllLines 和 java.nio.file.Files#readAllBytes 方法。

下面看各个例子,为能够实际用运,例子写在 main 方法里,并从文件获得一个 InputStream,代码中把可能要捕获的异常抛出来。再就是注意处理输入输出流时有涉及到字符集,字符集乱了就乱码了,默认字符集是 System.getProperty("file.encoding"),通常我们都用 UTF-8,异常 UnsupportedEncodingException 继承自 IOException。

下面的 6 个方法中应该有一个你能看得上的吧,用 Groovy,Scala 的除外,若未找到一个遂意的,告诉我,你有好办法更应该告诉我。

1. 使用 JDK 5 的 Scanner 阅读全文 >>

使用 sbt 的 np 插件自动创建目录结构和 build.sbt 文件

通常我们要创建一个 sbt 项目需要经历以下几步:

$ mkdir testscala && cd testscala      #创建项目目录 testscala,并进入该目录
testscala $  mkdir -p src/{main,test}/scala   #创建源文件目录结构,可能还需要 mkdir -p src/{main,test}/resources
$ vi build.sbt # 填入基本的信息 (name, organization, version)
$ sbt

这一看怎么这么复杂啊,特别是习惯了 Maven 的同学们更会这么觉得。Maven 不仅可应用各种模板来创建不同类型的工程,完整的工程目录结构都有了。

那么 sbt 能不能做到自动创建目录和配置文件呢,答案是: 本身不能。你可以基于一个项目模板目录结构拷来拷去。前面说是 sbt 本身不能,要知道 sbt 是一个插件化更彻底的玩意,如今的 0.12.2 的 sbt.zip 才 1M 大小,其余全赖插件帮你插来插去了。

因此,我们找来的 np(New Project) 插件 https://github.com/softprops/np 帮我们创建工程的目录结构和 build.sbt 文件。它能让我们创建项目的过程简化为以下两步操作:

$ mkdir testscala && cd testscala   #这一步还是不能少
$ sbt
> np name:testscala org:cc.unmi   #这样 testscala 下 {main.test}/{scala,resources} 和  build.sbt 文件都有了

np 的安装及使用可以参考:https://github.com/softprops/np,就是下面的步骤: 阅读全文 >>

Scala 2.10.0 新特性之字符串插值

Scala 在处理字符串方面终于也与时俱进了,引入了字符串插件,这在许多脚本语言中就早已这么做了。有了这个特性,字面量字符串和变量连接可以不需要总是用加号进行丑陋的连接了。有些脚本语言会是只对双引号字符串解析其中的变量,单引号的不会,当然Scala 是要区分字符串和字符类型。

直白的讲字符串插值就是,val name="Unmi"; val greeting=s"Hello $name"; greeting 的值就是 "Hello name"。产生效应的就是那个 s 方法。

Scala 2.10.0 为我们提供了三种字符串插值的方式,分别是 s, f 和  raw。它们都是定义在 StringContext 中的方法。

s 字符串插值器

可以解析字符串中的变量,可以调用方法,还能进行计算。实际调用的是  StringContext 中的  s 方法。 阅读全文 >>

Scala 2.10.0 新特性之动态属性、方法

最早的介绍 Scala 语言的书都是以 Scala 的静态类型系统为傲。Scala 也算是个脚本语言,却不像其他许多脚本语言那样类型是动态的,只有执行时才确定,而 Scala 在执行前就确定了类型,比如依赖于比 Java 更强大的类型推断行为。

静态类型不光是变量类型是确定的,还有比如在使用  qual.sel 时,sel 这个属性或是方法(Scala 的访问一致性,属性和方法有时候并没有那么大的区别)必须在 qual 的类型中声明了的。

Scala 思考再三还是加入了 Dynamic Types,这个特性在 Scala 2.9 中是试验性的,必须用 -Xexperimental 进行开启,到了 Scala 2.10.0 中,只有代码中 import scala.language.dynamics 就可用了,或是编译时加 -language:dynamics 选项。

虽然 Scala 2.10.0 加进了 Dynamic Types 特性,但 Scala 仍然是静态类型的语言,因为在编译器同样会检查多出来的类型。

有了 Dynamic Types 之后,Scala 又可更 DSL 了,方法名的动态上可以让它随时包括深刻的业务含义。相比 Java 的 DSL 的能力就太逊了,我们几乎无法在 Java 面前提 DSL 这回事。 阅读全文 >>

使用 Jackson 把 Java 对象转换成 JSON 字串

原来 Java 项目中用的 JSON 组件库主要是 Gson 和 json-lib,Gson 算是很错的库,json-lib 略显寒碜。好啦,最近 Play 2.x 中弃用了 Gson 而采纳了 Jackson,所以现在就来打探一下 Jackson,踩个点吧。

Jackson 号称非常高的性能,听说比另两位兄弟 Gson 和 json-lib 高出一大截,我没有亲测,可是有心人做了,看这个链接 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试) 中的数据。2010 年 8 月份的测试结果,不知现在随着版本的变更是否仍然保持着这种悬殊。

通常我会在把文章开头塞丰满,做足前戏,并不是因为在天涯混习惯了的缘故,况且我在天涯总是讷于言的; 在这里,自己的地盘自己作主,不会有要求码足多少字才能发表的自虐性需求,仅仅是让本文在主页上显示时的的概要不空洞而已,可以简单粗暴的称之为废话。

了了,先了解 Jacson 最贴近实际应用场景的应用,即 Jackson 怎么把一个 Java 生成对应的 JSON 字符串,看看前面的文字有这么多了,直接上一段代码吧,而后再慢慢假设与分解: 阅读全文 >>

Scala 2.10 新特性之使用隐式类进行类型隐式转换

在 Scala 2.10.0 之前类型的隐式转换必须通过隐式方法来完成,现在的 Scala 可以用 implicit class 来声明类,并且它的主构造器 (Primary Constructor) 只有一个参数时,就可以用来把参数隐式转换成该类型。

能理解上面什么意思,知道怎么用隐式类吗? 就上面那句话,我自己都不知道在说什么。

首先要知道 Scala 先前是怎么依据隐式方法进行类型的隐式转换,其次又何谓主构造器呢? 关于 Scala 2.10.0 的 implicit class,官方的解释在这里 http://docs.scala-lang.org/sips/pending/implicit-classes.html 再多说只能让大家更摸不到头,实例演示是王道:

scala-2.10.0-implicit-class 阅读全文 >>