Vim 插件之:vim-repeat

这个插件顾名思义,就是扩展了 vim 中 . 的功能,有些插件实现的复杂修改(比如修改 surrounding) 用原生的 . 无法实现,而用该插件可以实现。

Installation

Plug 'tpope/vim-repeat'

Usage

既然提到了 vim.repeat 就不得不提到 vim 的 . 操作。

  • 比如使用 diw 删除了一个 word,那么可以使用 . 来删除另一个 word
  • 如果使用 dd 删除了一行,那么可以使用 5. 来删除 5 行
  • 如果在 insert 模式下,输入 hello!,那么使用 ESC 进入 normal 模式,那么移动光标,在另外一个地方使用 . 可以快速输入 hello!

而如果使用 :help repeat 就会发现 vim 支持的 repeat,日常使用的 . 只不过是冰山一角。. 被叫做 single-repeat,vim 还支持

  • multi-repeat
  • complex-repeat
  • using-scripts

等等复杂的 repeat commands。

multi-repeat

vim 中的 multi-repeat 其实日常中也非常熟悉,比如 :2,5g/^$/d 这种类似的命令就被叫做 multi-repeat. 解释一下这个例子,就是从 2 到 5 行中匹配 ^$ (也就是空行) 的内容执行命令 d (删除)。

恢复到这个命令最原本的模式

:[range]g[lobal]!/{pattern}/[cmd]

这条命令的也是就是在行数范围 range 的行上,匹配 pattern 的行,执行 Ex command(默认是 :p)

:[range]g[lobal]/{pattern}/[cmd]

这条命令的也是就是在行数范围 range 的行上,匹配 pattern 的行,执行 Ex command(默认是 :p)

:[range]v[global]/{pattern}/[cmd]

:g!

几点说明:

  • 对于上面在 pattern 两边的 / 可以使用其他非字母单字节字符来替换,比如使用 \, ", |, 等,这种方式使得可以在 pattern 中直接使用 /
  • 对于这里的 cmd 是 vim 的 Ex cmd,使用 :help ex-cmd-index 来查看

常见的 Ex 命令

  • :d delete lines
  • :g execute commands for matching lines
  • :grep run ‘grepprg’ and jump to first match
  • :help
  • :insert
  • :ls
  • :m move lines
  • :new create a new empty window
  • :w write to a file
  • :wq
  • :x
  • :z

比如替换文本中所有 pat 为 PAT

:g/pat/s//PAT/g

同样也可以使用 :%s/pat/PAT/g

g 命令是一个非常强大的命令,更多的可以参考下一章节的 g 使用。

complex-repeats

更为复杂的 repeat ,那就需要使用到 vim 内置的 register 0-9a-zA-z"

q{0-9a-zA-z"}           " 来开启录制
q                       " 之后使用 q 来停止录制
@{0-9z-aA-Z".=*+}       " 执行 Register 中的内容,`%` 当前文件名,`#` 可选文件名,这两个 Register 不能使用
@@                      " 执行上一次

Power of g

delete all line match pattern

:g/pattern/d

delete all lines not match pattern

:g!/pattern/d
:v/pattern/d

copy all match lines to the end of file

:g/pattern/t$

move all match lines to the end of file

:g/pattern/m$

copy all lines matching pattern to register ‘a’

qaq:g/pattern/y A

说明:

  • qaq 清空 Register a
  • y A 是 Ex cmd (:help :y), yank the current line into register A (append to register a)

reverse entire file

:g/^/m0

reference


2014-11-03 vim , vim-plugin , tpope , vim-repeat

Google推出inbox的一点思考

前一天就看到Rumor说Google有一款inbox产品要发布,没想到今天一早就看到+Sundar Pichai 发了一Po 说发布这个产品了。第一时间申请了邀请码,可是到目前为止也没见邀请码的踪影,也就只能从一些介绍,截图,视频中看到一些端倪,也由此写下一些想法。 inbox with nexus 6

##改变 Gmail发布已有10年,这十年时间Gmail改变了人们使用邮箱的习惯,而这十年变化的东西太多了,邮箱这一概念早被人说是应该淘汰的东西,时至今日邮箱却依然还是日常生活,工作交流中很重要的一个环节,可是邮箱亟需要变革,不仅是作为用户而言,并且是邮箱服务提供商应该需要思考的问题,越来越多的垃圾邮件,越来越多的不必要的邮件出现在用户的收件箱。而今天Gmail团队给自己的服务一个evolution,虽然Gmail已经在不久前启用了分类服务,能够帮助过滤一些无用的邮件,但可能Gmail团队觉得还不够,他们要以一种智能的方式帮助用户收发邮件—-他们在官方博客上这样说:designed to focus on what really matters. 用户只需要关注他们真正需要关注的。改变总是好的,无论这个改变是好是坏,改变意味着不满足与现有的状态,期望以一种理想的状态而活着。所以无论这个服务是否会像waze失败,最后总会有收获inbox web design 图片来自Verge

##UI设计、功能变革 那就来看看这个服务让人耳目一新的功能,首先让人眼前一亮的就是UI的设计,无论是Web还是移动端,简直就是Material Design的推广,靓丽的颜色配合着无比流畅的动画,首先让使用者的体验就很爽朗。其次就是博客中宣传的:Bundles,Highlights,Reminders, Assists, and Snooze,这三个功能构成inbox的主体,虽然Bundles就是Gmail中的不同Tab分类,Highlights应该也就是Gmail中的星,Reminders,Assists,and Snooze也就是Gmail中的工作表,可是inbox给使用者的感受是不一样的,让我想到的第一个词语就是GTD,getting things done. 这个词我第一次接触是在本科上的一门校外选修课上老师讲的。邮箱的作用难道不是这个吗?原来我们转了大大的一圈又回到了邮箱最原始的作用,帮助工作生活交流,Gmail原来一种时间乱糟糟的顺序给我们安排,而inbox是以一种事情重要程度,get more import things done first.

##背后算法 说到inbox这里,就不免让我想起Google Now,想起Andrew Ng的机器学习,Google Now是Google推出的个人助手,机器学习是一门公开课,我们这学期也在学,inbox能够提供这样的一种服务,Google要在背后做的运算是及其大的,如果要做的更加智能要做的或许更多,一封邮件重要与否,一封邮件对于某一个个人重要与否,都需要背后很强大的算法计算得出。而同样你得提供更多的数据,所谓的给予的多,收获的更多。当然这只是我片面的想象,背后的数据谁也不知道,除非你去问Google的employee们。

##inbox展望 inbox作为Gmail的一个革新,无论如何我都是期待的。目前我还没用过还不知道真正的使用体验也就不好说什么了。只是Google各种产品的混乱逻辑也我也弄不清楚了,虽然Gmail一直有工作表这样的功能,但却把GTD的功能做的很烂,虽然之前的keep也有GTD类似的功能,却放在类似记事本一样的笔记类应用中。当然那些产品加上那些功能也不是多此一举,却一时间让人无法选择。我原本以为所谓的inbox应该是所有服务的一个inbox,当然Gmail是最最最重要的一个inbox,而Google+的通知呢?在Web上无处不在的通知难道不应该出现在inbox中?Blogger的评论呢?YouTube制作者的评论呢?或许那死了的Reader还有那个你关注的博客又更新了一篇文章呢?我原本以为的inbox是那样的,最后的结果是我真的想多了。 但转念一想,或许不久Google Now能够给我们提供吧,期待未来。


2014-11-02 Google , inbox , Gmail

手机信号字母表示

使用智能手机的朋友会发现,在手机信号旁边或者上面都会有一些奇怪的字母,比如3G、E、H等等,这些字母都代表什么意思呢?哪种网络状态速度最快?下面让我们详细了解一下吧!

  1. G指GPRS,它是GSM移动电话用户可用的一种移动数据业务,GPRS可说是GSM的延续,是2.5G网络。在iPhone手机上显示O;2.5G的速度约为10KB/s

  2. E指EDGE网络,是增强型数据速率GSM演进技术,属2.75G,速度约为20KB~30KB/s

  3. 3G指普通3G网络,在国内常见的3G有电信的CDMA2000、联通的WCDMA和移动的TD-SCDMA三种,速度在2-7M;

  4. H见于联通的WCDMA手机上,指3G的升级版HSDPA网络,是3.5G,速度可达14.4M;

  5. H+常见于中国联通的WCDMA手机上,hsdpa的升级版HSPA+,是3.75G,速度可达21M-42M;

从网络速度对比来看,从慢到快依次是 G<E<3G<H<H+

日常生活中,在使用手机的过程中,我们常常可以在屏幕的状态栏上方看到网络信号的标识,大概有G/3G/T/E/1X/H/H+这些信号标识,这些标志代表什么含义呢?

移动卡网络信号有:G、E、T(或者H)

China Mobile

G:G是GPRS通用分组无线服务技术(General Packet Radio Service)的简称,它是GSM移动电话用户可用的一种移动数据业务,GPRS可说是GSM的延续。GPRS的传输速率可提升至56甚至114Kbps,理论上资费较为便宜。具有高速数据传输速度10倍于GSM、永远在线、仅按数据流量计费的特点;

E:E是EDGE(Enhanced Data Rate for GSM Evolution)增强型数据速率GSM演进技术的简称,是一种从GSM到3G的过渡技术,GPRS到第三代移动通信的过渡性技术方案(GPRS俗称2.5G, EDGE俗称2.75G.)。现在中国移动的EDGE网络已经基本上覆盖全国,只有一些较为偏僻的地区无法访问,其传输速率在峰值可以达到384kbps,现在比较主流的无线网络传输方式;

T或者(H):T是TD-SCDMA(Time Division-Synchronous Code Division Multiple Access时分同步码分多址)的简称,其是中国提出的第三代移动通信标准(简称3G),也是ITU批准的三个3G标准中的一个以我国知识产权为主的、被国际上广泛接受和认可的无线通信国际标准。现在使用的版本是R4版本,理论下载数值为378.2KB/S。

移动卡的用户在信号不稳定时,手机可以在这些信号中自动转换,使你的手机基本通话要求得以保证不间断。

联通卡网络信号有:G、3G(或者H或者3.5G)、H+

unicom

G:这里不用介绍了,和移动的G是一样的,但是由于联通建的基站比较少,所以网络信号质量很差,大家都不愿意用了;

3G(或者H或者3.5G):HSDPA(High Speed Downlink Packet Access)高速下行分组接入,是一种移动通信协议,亦称为3.5G(3½G),它的下载速度理论呢是可以达到7.2Mbp/s。在国内的三大运营商中,联通的3G是做的最好的,很多人用;

H+:HSPA+的英文全称为 High-Speed Packet Access+,增强型高速分组接入技术,是HSPA的强化版本,最高的下行21Mbps,大部分HSPA+手机基本都是支持5.76Mbps的最高上行速度和21Mbps或者28Mbps的最高下行速度,相比较HSPA的速度更快。总的来说HSPA+比HSPA的速度更快,性能更好,技术更先进,同时网络也更稳定,是目前LTE技术运用之前的最快的网络!其属于联通3.75G网络,当前的联通3G网络覆盖较好。显示H+的时候网速是最快的,理论速率可以达到42Mbp/s的,也就是联通目前畅销的WO卡。

电信卡网络信号有:1X、3G

telecom

1X:1X即CDMA1x,也就是我们通常所说的电信的2G网络,CDMA1X手机上网的传输速率可达每秒钟144Kb,不过在现在的情况下,1X已经满足不了用户的需求了。不过电信2G(也就是1X)对比其它运营商的G属于是最稳定的,也是表现最好的信号;

3G:3G是指3G信号CDMA2000(EVDO.A),EV-DO是3G CDMA的技术名称,在手机上为了简便显示为3G,它的速率理论上达到3M,但实际上一般只有1.6M左右。它是基于移动网络的多址分发同时提供网络流量,这3家运营商的3G网络信号覆盖最好最广的就是电信的3G信号了,他的实测下载速度峰值可以达到290Kb/s左右,电信卡的资费理论上也比较便宜点;

reference


2014-10-24 Android , Knowledge

照片添加GPS信息

在玩Ingress之后的很长一段时间内,我觉得如果照片没有地理位置信息是一种缺失,而去年买的 Nikon 单反没有GPS模块,Nikon提供的GPS模块需要单独购买价格不便宜并且携带不方便,于是我找到一种既便宜又简洁的方式可以给照片添加上GPS信息。

需要借助的工具:

具体原理是:按照时间顺序,将手机记录的GPS信息写入相机拍摄的照片中。

具体步骤:

  1. 调校相机时间和手机时间保持一致
  2. 使用My Tracks应用记录GPS信息,保证在使用单反拍照前后一直在记录。所以最好的办法是出门前打开My Tracks,回家关闭记录。
  3. 回到家,导出照片,安装GeoSetter软件,将My Tracks记录的文件导出为gpx文件
  4. 打开GeoSetter,全选所有照片,在菜单中找到和GPS文件同步,快捷键Ctrl+G,找到Android手机中Export出的gpx文件,同步。
  5. Ctrl+S,保存。

之后GPS信息就被写到照片文件中了。


2014-10-02 DSLR , GPS , Nikon , 摄影

优化 Java 中正则表达式

Java 中和正则相关的工具类都在 java.util.regex 包下,Java 使用了 Nondeterministic Finite Automaton (NFA),之所以称为非确定性是因为当正则匹配给定字符串时,每一个字符都可能和正则匹配多次。这个匹配引擎被广泛的使用在 .NET, PHP, perl, Python, Ruby 中。很多人认为正则处理很快,很强大,但是其实不同正则表达式的写法可能导致消耗的时间和空间相差几十倍甚至上百倍,当在一些移动设备中使用正则时则要更加注意。

在引擎内部,NFA 使用回溯(backtracking) ,通常情况下针对给定的字符串,正则表达式可能有不止一种匹配方式,那么规则匹配引擎则会尽可能匹配所有可能,直到失败。

为了更好的理解 NFA 和回溯,举一个简单的例子,比如有一个正则表达式 sc(ored|ared|oring)x ,而输入的文本是 scared

在开始的时候,引擎会查找到 sc,立即找到匹配的前两个字符,接着会从第三个字符开始匹配 ored,发现不匹配则会尝试下一个可能 ared,这个匹配成功,继续匹配后面的 x,此时发现不成功,那么引擎会回溯回去匹配第三个可能 oring,同样也没有匹配。那么引擎会回溯到第二个字符开始继续匹配 sc,直到匹配到字符结尾,然后抛出匹配失败。

优化回溯

在上面的例子中就能看到,NFA 使用回溯来进行规则匹配,上面的例子也非常容易发现回溯的一个问题,就是即使是很简单的例子,也可能导致回溯非常多次。由此可以想象,当回溯失控时对应用程序的性能影响。因此优化正则表达式的一个很重要的部分就是尽量减少回溯的次数。

因为回溯的存在,在遇到现实复杂情况时,正则匹配可能需要花费大量时间来寻找完整的匹配。更糟糕的是,引擎花费大量的时间来匹配从而宣告一次失败,这个时间远比一次成功的匹配来得多。因此需要记住的是,当测试正则表达式的速度时,测试正则匹配不成功的时候,而不是测试成功的匹配。而当测试匹配时,则尽量使用刚刚好匹配的字符串,因为这种字符串花费最长的时间。

避免重新编译正则

当程序中需要不止一次使用相同的正则表达式时,预先编译好后使用。先使用 Pattern.compile() 定义好,而不是直接使用 Pattern.matches()matches() 方法内部每一次都会重新编译表达式。

并且记住对于不同的输入字符串,我们可以复用 Matcher 对象,不过要记住调用 reset() 方法。

合理使用括号

如果不需要引用括号内容,使用非捕获型括号 (?:PATTERN),节省捕获时间,减少回溯使用状态数量。只在必要时使用括号捕获。

不要滥用字符组

比如在 [Ff] 应当使用不区分大小写的匹配而不是字符组

准确表达意图

正则表达式提供很多结构(字符组,多选结构,量词等等),很多结构功能存在重叠,做同一件事情可能有不同的表达,这个时候应该选择最适当的结构。比如多选结构和字符组,多选结构完全覆盖了字符组。(a|b|c|d)[abcd] 匹配的文本是一样的,但是多选结构用于处理“可能出现若干表达式”,而字符组是专门用于处理“可能出现若干字符”的,这种情况字符组效率要远远高于多选结构。所以应当选择用 [abcd].

避免多选结构多个分支匹配相同文本

正则非常灵活,往往同一个表达式可能匹配多种不同形态的文本,但是如果一个表达式中包含若干”能匹配不同形态文本“的子表达式,那么子表达式能匹配的文本有重叠就可能有效率问题。

比如 a+a+,再比如 [0-9]+\w+ 前后连接部分产生重复匹配问题。

两条规则

  • 凡是 regex1*regex2*(量词不限于*) 的表达式,都要尽力避免 regex1 和 regex2 能匹配相同的内容
  • 凡是 (regex1|regex2) 的表达式,尽力避免 regex1 和 regex2 匹配相同的内容

使用起始终止锚点

除非是及其罕见的情况,否则以 .* 开头的正则表达式都应该在最前面添加 ^ 或者 \A 如果这个正则表达式在某个字符串的开头不能匹配,那么显然在其他位置它也不能匹配。添加锚点无论是手工添加还是通过优化自动添加都能够配合开头字符 / 字符串 / 字串识别优化,节省大量不必要的工作

在表达式前面独立出 ^ 和 \G

^(?:abc|123)(^abc|^123) 在逻辑上是等价的,但是许多正则引擎指挥对第一个表达式使用 开头字符 / 字符串 / 字串识别优化。所以第一种办法的效率高得多

在表达式结尾独立出 $

确定起止锚点能够提高匹配速度,如果使用了 $ 标记结尾,正则引擎会从符合条件的长度开始匹配,而略过目标字符串中其他不关心的字符。

暴露尽可能多的匹配部分

xx* 替代 x+ 能够暴露必须匹配的 x 同样,用-----{0,2}代替-{5,7}

th(?:is|at) 替代 (?:this|that) ,就能暴露出必须的 th。如果不同的多选分支的结尾部分相同,我们也可以从右面”提取”。例如 (?:optim|standard)ization

对于传统 NFA,一旦匹配到结果就会停止。

用字符组代替分支条件

比如对于想要匹配的 a 或 b 或 c 或 d,使用 [a-d] 而不要使用 (?:a|b|c|d)。字符组比使用分支条件速度快。

谨慎使用点号

谨慎使用点号,星号,加号这样的元字符,只要能确定范围,就不要用点号。只要能够预测重复范围,就不要使用量词。

别过分依赖正则

正则表达式确实很强大,但是不要过分依赖正则。

最常见的错误就是,只要字符串操作就能完成,但非要用正则。比如判定一个字符串以什么开头,或者什么结尾,或者判断是否包含某一个子串。

reference


2014-09-30 java , regex

log4j XML 配置

我们都知道 log4j 有两种配置文件的语法,本文主要介绍 XML 格式的配置格式。

log4j XML 配置的一些细节记录。

priority 和 level 的区别

我们都知道日志打印的级别,从低到高依次是 TRACE, DEBUG, INFO, WARN, ERROR and FATAL.

日常使用中经常会看到 root 或者 logger 节点配置 <level value="INFO"> 这样的语句,root 节点中也有 priority 的配置

<logger name="com.package">
    <level value="WARN" />
</logger>

<root>
  <priority value ="debug" />
  <appender-ref ref="console" />
</root>

定义了 priority 的 root 只会将 DEBUG 级别及其以上级别的日志发送到 Appender 中。logger 的 level 同理,只会将 WARN 级别和以上的日志发送到 appender 中。

他们的区别只在于 priority 在 root 中用,level 则 logger 中用。

appender 中 Threshold 的使用

appender 的配置

<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
   <param name="Threshold" value="ERROR"/>
</appender>

假设有如下两种情况。

priority value="DEBUG" and param name="Threshold" value="ERROR"

priority value="ERROR" and param name="Threshold" value="DEBUG"
  1. 第一种情况 Logger 设置优先级 DEBUG,appender Threshold 设置为 ERROR,意味着 logger 会将 DEBUG,INFO,WARN,ERROR 和 FATAL 级别的日志发送到 appender,但是 appender 只会接受 ERROR 和 FATAL 的日志,所以最后日志中只会有 ERROR 和 FATAL 级别的日志。
  2. 第二中情况,logger 设置为 ERROR,appender 设置为 DEBUG,意味着 logger 会将 ERROR 和 FATAL 级别日志 pass 到 appender,而 appender 能够接受 DEBUG,INFO,WARN,ERROR,FATAL 级别的日志,但最后的日志中也只有 ERROR 和 FATAL 级别的日志。

所以两者的最后结果是一致的。组合二者的使用能够更有效率的打印测试环境或者生产环境的日志。

同一份日志打印到多个地方

定义不同的 appender ,然后在 logger 中定义多个在 pass 到 appender 即可。

不同的 package 使用不同的 appender

则在定义 logger 时 name 中指定对应的 package name,然后引用对应的 appender。

不同的 appender 相同的文件

log4j 不支持不同的 appender 打印到相同的文件中。

reference


2014-09-28 log4j , log4j12 , log4j12-config

正则学习指导

从开始接触正则到现在已经过去很多年了,然而依然没有完全学会正则,每一次回顾的时候总是有很多很多的新东西。

什么是正则,看中文非常抽象,而英文 regular expression 就好理解得多,regular expression 它是一个有规律,常规的,经常需要用的表达式,究其根本就是一个用来搜索特定字符串的表达式,这个表达式遵循一定的规律,有自身的逻辑表达,通过这种通用的方式可以写出比较容易理解的搜索语句。

根据维基百科的说明 正则一词是美国数学家 Stephen Cole Kleene 于 1950s 正式使用。而这个概念则是在 1980s 因为 Unix 下文本编辑器工具的使用而变得常见。自此之后正则的语法规则 POSIX 和 Perl 区别。

常用表达

表示或

gray|grey

表示匹配 gray 或者 grey 两个单词

分组,用来定义边界,或者确定执行顺序

gr(a|e)y

和上面表达等效

常见的定量表达

?       表示前面的字符出现 0 次或者 1 次
*       表示前面的字符出现 0 次或者多次
+       表示前面的字符出现 1 次或者多次
{n}     表示前面的字符出现 n 次
{m,}    至少 m 次
{m, n}  m 到 n 次

通配符 . 可以匹配任何一个字符

字符组 Character class

字符组 Character Class 是一个比较好理解的,就是一组字符,用方括号来标示,表示匹配其中某一个字符。比如常见的

[aef]
[0-9]
[a-zA-Z]

字符组中的范围表示使用的是 ASCII 编码中的码值,所以不能写成 [9-0]

排除型字符组,在方括号后增加 ^

[^0-9]       # 非 0-9
[^ae]       # 非 a 或 e

字符组简记法,常见的字符组,比如数字,英文字符组,可以用简单的缩写形式来表示。

\d      [0-9]

元字符 meta-character

比如字符组中的 - 还有括号 [, ] 还有常见的 ^, $ 这些特殊意义的字符都是元字符。如果遇到想要匹配这些特殊的字符就需要转义。

^
$
.
[]
[^]
*
()
{}
\b          单词边界
\d          [0-9]
\w          字母数字下划线和汉字
\s          任意空白

后向引用

当用小括号指定子表达式后,匹配这个子表达式的文本(分组捕获)会自动拥有一个组号,从左到右,分组的左括号为标志,出现的第一个分组为 1,其后 2,3,4 类推。

后向引用则可以利用分组捕获的文本来匹配比如重复的单词

\b(\w+)\b\s+\1\b

其中的 \1 在表示引用前面 (\w+) 括号中捕获的文本,比如 go go 则会被匹配。分组捕获通常用在想要获取匹配字符串中部分子串时使用。

但是在使用捕获时一定要注意,过多的捕获会影响正则表达式的效率,如果不需要捕获则可以使用

(?:exp)

来忽略捕获的内容。

分组还有一些其他的语法

(?<name>exp)        匹配 exp,将捕获的文本放到名字为 name 的组,也可以写成 (?'name'exp)
(?#comment)         注释,无任何作用

零宽断言

了解零宽断言需要分两部分来理解,第一是匹配宽度为 0,第二断言表示满足一定的条件。匹配宽度指的是匹配时占字符宽度,比如在匹配不包含 a 或 b 开头的单词时,如果使用 [^ab] 那么 [] 则会占用一个字符宽度。零宽断言用于查找在某些内容(但并不包括这些内容)之前或之后的东西时。

零宽断言的英文是 Lookahead and Lookbehind Zero-Length Assertions 这就好理解很多了,就是正则表达式先要匹配的内容往前或者往后的断言,也就是比如我想要匹配的一串数字必须在 id= 后面就可以使用先行断言

(?=id=)\d+

零宽断言又分四种

(?=exp)         断言自身出现的位置的后面能匹配表达式 exp
(?<=exp)        断言自身出现的位置的前面能匹配表达式 exp
(?!exp)         断言此位置的后面不能匹配表达式 exp
(?<!exp)        断言此位置的前面不能匹配表达式 exp

先行断言

先行断言,也叫零宽度正预测先行断言 (?=exp) 表示匹配表达式前面的位置

比如,b\w+(?=ing\b) ,匹配以 ing 结尾的单词的前面部分(除了 ing 以外的部分)

注意:先行断言的执行步骤是这样的,先从要匹配的字符串中的最右端找到第一个 ing(也就是先行断言中的表达式)然后再匹配其前面的表达式,若无法匹配则继续查找第二个 ing 再匹配第二个 ing 前面的字符串,若能匹配则匹配

例如: .*(?=ing) 可以匹配 cooking singing 中的 cooking sing 而不是 cook

后发断言

后发断言,也叫零宽度正回顾后发断言 (?<=exp) 表示匹配表达式后面的位置

例如 (?<=abc).* 可以匹配 abcdefg 中的 defg

注意:后发断言跟先行断言相反,它的执行步骤是这样的:先从要匹配的字符串中的最左端找到第一个 abc(也就是先行断言中的表达式)然后 再匹配其后面的表达式,若无法匹配则继续查找第二个 abc 再匹配第二个 abc 后面的字符串,若能匹配则匹配

例如 (?<=abc).* 可以匹配 abcdefgabc 中的 defgabc 而不是 abcdefg

负向零宽断言

负向零宽断言 (?!exp) 也是匹配一个零宽度的位置,不过这个位置的“断言”取表达式的反值,同样,负向零宽断言也有“先行”和“后发”两种,负向零宽后发断言为 (?<!exp)

比如说想要匹配文本中所有等号后面的数字,但是就是不想匹配 id=123 这样 id= 开始的数字

(?<!id)=\d+

这四个断言的中文翻译的太烂了,完全不知道说的什么,用英语解释就清晰很多。

Atomic groups

Atomic groups 光看字面意思完全无法理解,但是如果举例说明,比如

a(bc|b)c

这是一个普通的分组正则,可以匹配 abcc 或者 abc,但是

a(?>bc|b)c

使用 Atomic groups 之后则只能匹配 abcc 而不能匹配 abc.

Atomic groups 在匹配 abc 时,括号中匹配到 bc 就退出了,而此时无法匹配括号外的 c 则失败了。

Atomic groups 会查找到第一个匹配的子串,然后就退出匹配,也不会回溯。所以如果在一些匹配到第一项,而后面不需要考虑的情况下可以使用 Atomic groups。

实例

比如说字符串 foobarbarfoo:

bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)

组合使用:

(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)

表示匹配 bar 要求前面是 foo 而后面是 bar,那么就匹配第一个 bar 了。

Look ahead positive (?=)

Find expression A where expression B follows:

A(?=B)

Look ahead negative (?!)

Find expression A where expression B does not follow:

A(?!B)

Look behind positive (?<=)

Find expression A where expression B precedes:

(?<=B)A

Look behind negative (?<!)

Find expression A where expression B does not precede:

(?<!B)A

Atomic groups (?>)

An atomic group exits a group and throws away alternative patterns after the first matched pattern inside the group (backtracking is disabled).

  • (?>foo|foot)s applied to foots will match its 1st alternative foo, then fail as s does not immediately follow, and stop as backtracking is disabled

A non-atomic group will allow backtracking; if subsequent matching ahead fails, it will backtrack and use alternative patterns until a match for the entire expression is found or all possibilities are exhausted.

  • (foo|foot)s applied to foots will:

    1. match its 1st alternative foo, then fail as s does not immediately follow in foots, and backtrack to its 2nd alternative;
    2. match its 2nd alternative foot, then succeed as s immediately follows in foots, and stop.

网页

匹配网页标题

<head>([^<]+)</head>

然后取分组 1

网页图片

<img\s+[^>]*? src=['"]?([^"'\s]+)['"]?[^>]*>

取分组 1

身份证

简单版本,不精确

[1-9]\d{14}
[1-9]\d{14}\d{2}[0-9xX]

reference


2014-09-27 regex , regular-expression , java , python , nlp

log4j 根据 package 打印日志到不同目的地

log4j 可以配置不同的包打印到不同的 appender 中,通过在配置中添加如下配置。

<!-- 这里的 additivity 配置了该 package 下的 appender 是否需要传递到 root , 默认为 true , 造成日志打印两遍 -->
<logger name="com.jutils.appender.LogLevelATest" additivity="false">
  <level value="INFO"/>
  <appender-ref ref="consoleAppender"/>
</logger>
<logger name="com.jutils.appender.LogLevelBTest" >
  <level value="WARN"/>
</logger>

定义 logger 在 name 中指定需要 include 的 package full path,然后在 appender-ref 中指定需要打到的 Appender 中。


2014-09-27 log4j , log4j12 , log4j12-conf , log4j12-xml

记账 App 选择

很久之前产生记账的需求,所以当时试用了市场上很大一批的记账软件和 App,我的需求无非有几样:

  • 多平台同步,至少 Web,Android 平台有产品
  • 记账方便,随时随地能够使用
  • 界面简洁美观,能方便查看使用记录,和历史统计信息
  • 方便导出

在使用了近半年之后,我终于稳定的在使用一款叫做“随手记”的记账软件了。而事实上我看到很多 Google+ 的好友在使用类 Excel 工具记账,我也曾经使用过一段时间的 Excel,却没有坚持下来。使用这样一类工具时,我总感觉不是很方便,虽然也可以使用 Dropbox 或者其他工具同步到手机上,再使用 Office 打开编辑,但是终究多了些步骤。

过去一段时间我试用过的应用有:

随手记的开发人员是中国人,所以使用习惯还是挺符合国人的。当然对于基本的记账功能,随手记和 Expense Manager 都是有的。只是最后归结到细节的功能上,Expense Manager 只有 Android 端,虽然 UI 符合 Holo 风格,界面简洁明了,但是细节的功能太少,不值得玩味,并且不支持同步,虽然 Expense Manager 能够导出到 Excel,但还是将流程复杂了。 而随手记,有几个功能确实非常实用:

  • 丰富的分类,和子分类
  • 记账模板
  • 周期自动记账

虽然一开始我觉得随手记的分类太过复杂,记一笔账还得找好一会儿分类,但是用过一段时间之后发现其实这样对于以后查看使用是很有帮助的,并且分类和子分类都可以自定义,非常方便。而记账模板则是可以自定义一套模板,之后记录相同的账目可以套用一套模板。对于一些经常记录的分类,比如早午晚餐,周期性的购物都可以使用一套模板。另外周期自动记账就是可以将每月固定的支持,收入自动记录账目。

想要了解更多 Expense Manager 可以到电脑玩物

另外一些记账软件

2018 06 08 更细

最近又发现一款设计精致使用方便的记账应用,叫做 圈子账本 核心概念就是记账,能够同步账本,共享账本,初体验感觉似乎适合轻量的记账需求。有需求的人可以体验体验。至于我虽然限免的时候下载了 Pro 版本的记账,但于我,还不想迁移到这个应用来,虽然设计体验都还不错,但是因为之前一直用的随手记,加之基本消费都用信用卡,所以单独再去换一个记账 App 也没有什么必要了。 PS. 支持 Android 和 iOS。

写下这段文字的时候,边写边看了他们官网的宣传视频,提到这款产品 15 年上市,想来写下这篇文章竟然已经过了 4 年。这 4 年里老牌的随手记依然还在,新出来很多记账软件,各有各的特点,选择一款,然后记录吧。


2014-09-09 android , web , android-app , app , ios

电影版本中的缩写是什么意思

在网络下载资源时经常遇到一些整齐划一的命名,于是产生了这样的疑惑。

CAM(枪版)

CAM通常是用数码摄像机从电影院盗录。有时会使用小三角架,但大多数时候不可能使用,所以摄像机会抖动。因此我们看到画面通常偏暗人物常常会失真,下方的 字幕时常会出现倾斜。 由于声音是从摄像机自带的话筒录制,所以经常会录到观众的笑声等声音。因为这些因素,图象和声音质量通常都很差。

TS(准枪版)

TS是TELESYNC的缩写。TS与CAM版的标准是相同的。但它使用的是外置音源(一般是影院座椅上为听力不好的人设的耳机孔)这个音源不能保证是好的音源,因为受到很多背景噪音的干扰。TS是在空的影院或是用专业摄像机在投影室录制,所以图象质量可能比CAM好。但画面的起伏很大。论坛上常出现的有一般TS版和经过修复清晰TS版

TC(胶片版)

TC是TELECINE的缩写。TC使用电视电影机从胶片直接数字拷贝。画面质量还不错,但亮度不足,有些昏暗。很多时候制作TC使用的音源来自TS,因此音质很差,但画面质量远好过TS。如果不是太讲究的话TC版还是不错的选择。

DVDSCR(预售版)

SCR是SCREENER的缩写。DVDSCR预览版的或者是测试版的DVD,非正式出版的版本。从预览版 DVD 中获取,通过mpeg-4技术进行高质量压缩的视频格式。能比DVDRip早发布,但画质稍差。(经常有一些不在黑边里在屏幕下方滚动的消息,包含版权和反盗版电话号码 ,会影响观看。)如果没有严格的划分它的画质应与TC版差不多。

R5(俄罗斯5区版)

俄罗斯5区版的DVD,因为配音为俄语,所以需要去寻找英语音轨,R5版本就是一种合成版本(俄5区DVD视频+通过其它渠道获得的英语音轨),R5版本的画质一般都不错,音频部分由于音轨的来源不同,效果有好有差。

这里的 R=Region 美国电影协会划分的DVD区域码有:

  • 第一区:美国、加拿大; 第二区:日本、欧洲、埃及、南非、中东;
  • 第三区:中国台湾、中国香港特别行政区、南韩、东南亚;
  • 第四区:澳洲、新西兰、中南美洲、南太平洋岛屿;
  • 第五区:俄罗斯、蒙古、印度、中亚、东欧、北韩、北非、西北亚一带等;
  • 第六区:中国(除台、港地区)

HD RIP(高清版)

HDRip 是HDTVRip(高清电视资源压缩)的缩写,是用DivX/XviD/x264等MPEG4压缩技术对HDTV的视频图像进行高质量压缩,然后将视频、音频部分封装成一个.avi或.mkv文件,最后再加上外挂的字幕文件而形成的视频格式。画面清晰度更高。

BD(蓝光版)

BD是Blue Disk的简称,翻译成中文是“蓝光影碟”的意思。就是从蓝光影碟转录的视频和音频,画面清晰度很高。

DVD,HDVD,DVD5,DVD9

DVD的英文全名是Digital Video Disk,即数字视频光盘或数字影盘,它利用MPEG2的压缩技术来储存影像。

HDVD(压缩碟或者经济版DVD)

HDVD俗称压缩碟或者经济版DVD,介质通常为DVD-5(容量4.7G)也有DVD-9的(容量8.5G),采用MPEG-1或MPEG-2编码,由于码流较低,所以每张盘可容纳长达7个小时的视频节目,画质水平略高于或等同于VCD。用于看连续剧最省钱。

VHSRip

VHSRip是从零售版VHS录象带转制,主要是滑冰/体育内容的发布。

TVRip

从电视(最好是从数码有线电视/卫星电视捕捉)转制的电视剧,或接收由卫星提前几天向电视网传送的预播节目(不包含加密但有时有雪花)。有些节目,比如WWF RAW IS WAR包含多余的部分;”DARK MATCHES”和CAMERA/COMMENTARY测试被包含在TVRip里。PDTV是从PCI数码电视卡捕捉,通常效果最好;破解组织倾向于使用SVCD来发布。VCD/SVCD/DivX/XviD rips也都被用于发布TVRip。

WORKPRINT (WP)

WORKPRITN (WP)是从未完成的电影拷贝转制而成,可能会缺失镜头和音乐。质量可能从最好到很差。有些WP可能和最终版本相差很远。(MEN IN BLACK的WP丢失了所有的外星人,代之以演员);另一些则包括多余的镜头(Jay and Silent Bob). WPs可以作为有了好质量的最终版本后的附加收藏。

DivX Re-Enc

DivXRe-Enc是从原始VCD发布用DivX编码成的小一些的文件。通常可在文件共享网络找到。它们通常以 Film.Name.Group(1of2)等形式命名。常见的发布组织有SMR和TND。这些版本通常不值得下载,除非你不清楚某部电影,只想要200MB的版本。一般应避免。

Watermarks

很多从Asian Silvers/PDVD (参看下面)来的电影带有制作人的标记。通常是一个字母,名字缩写或图标,位于屏幕一角。最有名的是”Z”,”A”和”Globe”。

Asian Silvers / PDVD

Asian Silvers / PDVD是亚洲盗版商发行影片的,通常被一些发布组织购买来当做他们自己的发布。Silvers很便宜,在很多国家都很容易找到。发布Silvers很容易,所以现在有很多发布,主要是由一些小的组织发布;这些组织通常发布几个RELEASE后就不见了。PDVD和Silver一样,不过是压在DVD上。 PDVD通常有外挂字幕,质量也比Silver好。PDVD象普通的DVD一样转制,但通常用VCD的格式发布Scene Tags发布文件的标志。

PROPER

根据发布规则,最先发布Telesync (TS)的组织赢得(TS发布的)比赛。但是,如果这个发布版本质量很差,同时另一组织有另一TS版本(或质量更好的同一片源),那么标记PROPER被加到目录上以避免重复。PROPER是一个最主观的标记,很多人会争论是否PROPER比原始发布版本好。很多发布组织只不过因为输掉了发布比赛而发布 PROPER。发布PROPER的原因因该总是包含在NFO文件里。

SUBBED

对于VCD发布而言,SUBBED通常表示字幕被压进了电影。它们通常是马来语/中文/泰文等,有时有两种语言。它们可能占据了很大一部分屏幕。SVCD支持外挂字幕,所以DVDRip用外挂字幕发布。这些信息可以在NFO文件中找到。

UNSUBBED

当一部电影曾经发布过有字幕的SUBBED版本,没字幕的UNSUBBED版本也可能发布。

LIMITED

LIMITED电影指该电影只在有限的电影院放映,通常少于250家。通常较小的电影(比如艺术电影)的发行是LIMETED。

INTERNAL

INTERNAL发布有几个原因。经典的DVD组织有很多.INTERNAL.发布版本,这样不会引起混淆。同时,低质量的发布会加以 INTERNAL标记,这样不会降低发布组织的声誉,或由于已经发布的数量。

INTERNAL发布可以正常的在组织的会员网站上获取,但没有其他网站管理员的要求它们不可以被交换到其他网站。一些TERNAL发布仍然流到IRC/NEWSGROUP,这通常取决于电影及其流行度。今年早些时候,人们把 CENTROPY做为INTERNAL。这表示发布组织只向其会员和网站管理员发布。这和其通常意思不同。

STV

STV表示电影从未在电影院放映过就被发布,因此很多望网站不允许STV。

ASPECT RATIO TAGS

ws表示宽银幕,FS表示全屏幕。

RECODE

RECODE是以前已经发布过的版本,通常用TMPGenc编码过滤以去除字幕,纠正颜色等。虽然它们看起来好一些,但通常不认为这是好的行为因为发布组织应该去找他们自己的片源。

REPACK

如果发布组织发布了一个坏的版本,他们会发布REPACK来解决这些问题。

NUKED

一个发布可能因为多种原因被NUKE掉。有些网站会因为违犯他们的规则而NUKE发布(比如不允许发布TS版本)。但如果发布的版本有很大的问题(如20分钟没有声音,CD2是错误的电影或游戏),那么所有的网站都会NUKE这个发布。在这些网站上交换NUKED版本的人会失掉他们的信誉。但NUKED发布仍然可以通过P2P/USENET传播,所以应该总是首先找到其被NUKE的原因以防万一。如果发布组织发觉他们的发布有问题,他们可以要求NUKE。


2014-09-03 Movie , Knowledge

电子书

最近文章

  • Substratum Android 上的主题引擎 Substratum 是一款 Android 上的主题工具,能够不用 root 来达到系统级主题修改。并且在该工具下有一群爱好者和社区开发了无数的美观且实用的主题。Substratum 开始于以前非常流行的 CyanogenMod, Cyanogen 内置了该主题引擎,并使得修改主题异常简单。但是不幸的是,Cyanogen 没有继续下去, 但是 Substratum 死灰复燃。最初的时候 Substratum 还需要 Root 来使用,但是 Android Oreo 之后就可以不依赖于 Root 了。
  • Flask Babel 使用 Flask babel 是 Flask 的语言扩展,允许非常简单的方式让 Flask 支持多语言。
  • Android 内核中的 CPU 调频 CPU 调频模块主要分为三块:
  • QQ 音乐 qmcflac 文件解密 首先说重点,代码来自:
  • Vim 插件之全局搜索:ack.vim 这篇文章看开始陆陆续续记录一下用过的 Vim Plugin,虽然有些一直也在用但从没有好好整理过,正好这篇开一个计划吧。