博客分类 ‘一箩筐’

正则表达式中的非获取匹配

正则表达式是代码中的常用技巧,主要用来匹配符合某种句法规则的字符串。常用的正则表达式本文不再赘述,详细可以参考wikiPythonJava)。本文主要讨论的是非获取匹配的正则表达式。

常见的非获取匹配有以下几种:

(?:pattern) 主要用来匹配pattern但不获取结果。我们看下面的例子。

>>> re.match("win (7|vista)", "win 7").group()
'win 7'

>>> re.match("win (7|vista)", "win 7").groups()
('7',)

>>> re.match("win (?:7|vista)", "win 7").group()
'win 7'

>>> re.match("win (?:7|vista)", "win 7").groups()
()

可以看出,使用这种模式括号中匹配内容并没有存储供以后使用。它是比“win 7|win vista”更加简便的形式。

以上是Python的示例,Java代码如下(以后的例子不再赘述):

Pattern ptn = Pattern.compile("win (7|vista)");
Matcher m = ptn.matcher("win 7");
while (m.find()) {
    for (int i = 0; i <= m.groupCount(); i++) {
        System.out.println(m.group(i));
    }
}

(?=pattern) 正向肯定预查。它在任何匹配pattern的字符串处查找字符串,它仅仅是检查是否匹配,而不将预查的结果包含其中。当然,它也是非获取匹配。看个例子就明白了。

>>> re.match("win (?=7|vista)", "win 7").group()
'win '

>>> re.match("win (?=7|vista)", "win 7").groups()
()

(?!pattern) 正向否定预查。例子如下:

>>> re.match("win (?!7|vista)", "win 8").group()
'win '

>>> re.match("win (?!7|vista)", "win 8").groups()
()

(?<=pattern) 反向肯定预查。查找某个字串之前是否满足pattern。

>>> re.search("(?<=95|98)win", "98win").group()
'win'

>>> re.search("(?<=95|98)win", "98win").groups()
()

(?<!pattern) 反向否定预查。

>>> re.search("(?<!95|98)win", "7win").group() 
'win'

>>> re.search("(?<!95|98)win", "7win").groups()
()

现在我们来看实际中的需求。现在我有一个字符串,这个字符串是由中文和英文组成,现在我要把这个字符串切成一个个只由中文或者英文组成的字串。比如说将“McCulloch与Pitts将神经系统”切成”McCulloch“、“与”、“ Pitts“、”将神经系统“。

首先要知道匹配中文的正则是”[\u4e00-\u9fa5]“,在Python中,我们可以使用findall方法:

reg = re.compile(u"[\u4e00-\u9fa5]+|[A-Za-z]+")
print "\t".join([w for w in reg.findall(u"McCulloch与Pitts将神经系统")])

对于Java,除了使用这种方式匹配,我们还使用刚刚说过的非获取匹配来达到同样的效果。对于需求的句子,可以看到要切分的地方,要么是中文接英文,要么是英文接中文。所以我们在反向肯定预查到中文然后正向肯定预查到英文处调用split操作,或者在反向肯定预查到英文正向肯定预查到中文处调用同样的操作。于是有:

Pattern ptn = Pattern.compile(
    "(?<=[\u4e00-\u9fa5])(?=[A-Za-z])|(?<=[A-Za-z])(?=[\u4e00-\u9fa5])", 
    Pattern.UNICODE_CASE);
String[] words = ptn.split("McCulloch与Pitts将神经系统");
for(String word: words) {
    System.out.print(word + "\t");
}

可以看到达到了一样的效果,但是,在我的测试中,此法对Python中的正则库中的split方法并不适用。所以我们解决问题确实需要灵活多变的策略。

最后,我们再讨论以下js的实现。对于js来说,由于js不支持反向预查。所以,用和Python方法类似的简单策略。我们使用加上“g“修饰符的match方法(表示全局匹配,而不是只匹配一次)。

var testStr = "McCulloch与Pitts将神经系统";
var regExp = /[\u4e00-\u9fa5]+|[A-Za-z]+/g;

testStr.match(regExp).forEach(function(i){
    document.write(i+"  ");
});

windows下安装opencv

opencv(open source computer vision library)是一个基于C/C++语言的开源图像函数处理库。

它的主要模块包括:

  • cv —— 核心函数库
  • cvaux —— 辅助函数库
  • cxcore —— 数据结构与线性代数库
  • highgui —— GUI函数库
  • ml —— 机器学习函数库

opencv是跨平台的,支持包括windows、unix以及android等平台。下图是英文wiki上一张关于opencv概述的图。关于opencv的一系列功能以及特性,本文不再赘述,如果要了解,请移步至opencv的中文站点介绍

opencv overview

本文将会讲解在wndows上如何使用VS2010安装opencv,并以一个简单的程序作为结束。opencv在近期推出了2.3版本,不过本文仍然以2.2版本为例。其他安装请参考中文安装页面

用PIL实现滤镜

本来想写一个系列,已经有了第一篇《用PIL实现滤镜(一)——素描、铅笔画效果》。最后关于各种滤镜的计算方法,分系列写实在是乏善可陈。

目前,由于Python语言限制,有些算法的效率十分低下(比如油画——oil painting)。在完成全部预计的效果之后,会再考虑优化效率。其实做这个东西完全是学习之用,估计也没有什么太大的实用价值:)

现在,代码已经托管在bitbucket上,如果你感兴趣,可以查看wiki。要获得代码,运行命令:

$ hg clone http://bitbucket.org/chineking/pil-filter-extension

代码中都有详细的注释,具体细节请参考代码。

用PIL实现滤镜(一)——素描、铅笔画效果

在计算机图形学发展史中,真实感绘制一直是主旋律。不过从20实际90年代中期开始,非真实感图像绘制(Non-Photorealistic Rendering,NPR)逐渐成为一个研究热点。说白了,真实感绘制目标是像照片般真实地再现客观世界,而非真实感图像绘制专注于图形个性化和艺术化的表达,它主要用来表现图形的艺术特质,以及模拟艺术作品(甚至包括作品中的缺陷)。

在介绍完非真实感图像绘制之后,我们再来提及一下PIL——Python Imaging Library(官方网址)。相信使用python的朋友们都不会陌生,因为在web应用中我们常常用它来生成缩略图。从名字也可以看出,PIL主要用来处理图片,它支持多种图片格式,并提供强大的图片和图像处理能力。详细的关于PIL的内容大家可以参阅手册

这个系列,我们就主要使用PIL来进行滤镜方面的处理,包括素描、铅笔画、油画等等滤镜效果的实现。在以后我会把代码托管出来。

PIL已经内置一些滤镜效果,详细见文档这篇文章

黑白反转游戏

声明:这篇文章中涉及的游戏来自@陈荣峰ayuLemon的创意,文章的主要目的还是研究这个游戏其中的算法,我所写的网页版的游戏版本也仅仅是为了验证算法的正确性。说明这个是防止大家误认游戏乃我的原创。本来原作者要求我不能在他的算法出来之前发出此文,我百思不得其解。我认为这个没有先后顺序,思前想后,还是发出来了。仅讨论之用。

事情的起因是这样的,在我又度过了一个不眠之夜、正打算睡觉之时,看到@python4cn 转发了一个同学的微博,原文是这样的:

@陈荣峰ayuLemon:用python做了个小游戏,这是5*5方格。每点击上面的方格一次,就改变周围四个方格和被点击方格的颜色,对于任意n*n方格,可否通过若干次点击使方格的颜色与最初完全相反??(3*3和4*4的都很容易~~这个5*5的似乎有困难) 大家帮忙想一想,证明行或者不行,哪些行,哪些不行~~

baw

本来已经很困的我看到这个,又勾起了我的好奇。于是拿起纸笔,开始演算。当然首先从2×2开始,一直到4×4,确实没有什么困难。到5×5,算了很久才算出一个结果。

在分析这个问题之前,如果你想试玩,我做了一个网页版的,地址在这里

关于作者

残阳似血(@秦续业),程序猿一枚,把梦想揣进口袋的挨踢工作者。现加入阿里云,研究僧毕业于上海交通大学软件学院ADC实验室。熟悉分布式数据分析(DataFrame并行化框架)、基于图模型的分布式数据库和并行计算、Dpark/Spark以及Python web开发(Django、tornado)等。

博客分类

点击排行

标签云

扫描访问

主题

残阳似血的微博