Firefox的工具菜单中有个非常有用的功能:清除隐私数据,快捷键是Ctrl-Shift-Del。 经常做Web开发的人对这个功能一定非常熟悉,修改完一点代码看看效果时,都需要 Ctrl-Shift-Del然后按回车。
不过这个功能有个很郁闷的地方。Firefox 2中,默认是不清除网站登录信息的, 比如你登录了Gmail并选择下次无需输入密码,在Firefox 2中直接按Ctrl-Shift-Del再回车, 是不会清除Gmail上记忆的密码的。但是在Firefox 3中添加了一个很讨厌的选项, 清除“已通过验证的会话”,而且是默认选中的,这样直接Ctrl-Shift-Del再回车, Gmail上记住的密码也就没有了,下次进入Gmail还得再点一次登录。
幸好,通过about:config可以修改清除隐私数据对话框的默认值。 在地址栏中输入about:config,然后查找 privacy.item, 把 privacy.item.sessions 改为false就可以了。 这样再按 Ctrl-Shift-Del,“已通过验证的会话”选项就是默认不选中了。
众所周知Word的绘图功能是出了名的弱,很奇怪微软有钱去弄什么 信息检索 也不愿意下功夫把绘图功能改得好用些。这不,我只想要这样一个简简单单的圆角, 用Word的曲线功能画了一个小时也没能画得完美无缺。

好在Word还不是无药可救,它支持把wmf文件转换成绘图对象, 这样只要用其他软件画好图之后存成wmf,再导入Word就可以了。 那么做wmf用什么软件呢?手边有Illustrator和AutoCAD, 试了试AutoCAD的导出为wmf格式挺好用,就是它了。
2008-8-18更新 :今天发现这个名为Dia的自由软件 也能方便地绘制wmf格式的图片。如果不需要特别精确的定位,又无法使用AutoCAD的话, Dia也是个非常不错的选择。
阅读全文 »Office 2003的这个“信息检索”功能非常烦人,本来我们做程序员的就没什么需求要“研究”什么东西,而且这个功能一旦启动就要花掉几秒钟的时间去搜索辞典、搜索网络,何况公司的局域网内它根本就搜不到任何内容,更要命的是它的快捷键居然是Alt+单击这个极其容易误操作的组合……所以它不仅仅是鸡肋,而且是生产力发展的巨大障碍了。
不过搜索了一下,发现虽然不论在中文圈、日文圈还是英文圈中这个功能都是臭名昭著,人人都想禁用之而后快,但无一例外的答案都是“不可能”。不过好在虽然不能禁用Alt+Click的快捷键,但可以让信息检索窗口不去搜索网络和词典。这样尽管仍然会误操作,但可以省去那几秒钟的假死,也算可以接受了。
方法如下:
- 打开 HKLM\SOFTWARE\Microsoft\Office\11.0\Common\Research\Options,建立两个键值:NoAdd:DWORD=1,NoDiscovery:DWORD=1。据说可以禁止信息检索功能访问网络。
- 删掉 HKCU\Software\Microsoft\Office\11.0\Common\Research 下的所有东西。貌似删掉 Sources 主键之后就不会再搜索辞典了。
然后重新启动Office就可以了。
微软开发了这样一个阻碍生产力的功能,反过来还要我们为这个功能付钱,……
毋庸多言,在vim中正则表达式得到了十分广泛的应用。 最常用的 / 和 :s 命令中,正则表达式都是不可或缺的。 下面对vim中的正则表达式的一些难点进行说明。
关于magic
vim中有个magic的设定。设定方法为:
:set magic " 设置magic :set nomagic " 取消magic :h magic " 查看帮助
vim毕竟是个编辑器,正则表达式中包含的大量元字符如果原封不动地引用(像perl那样), 势必会给不懂正则表达式的人造成麻烦,比如 /foo(1) 命令, 大多数人都用它来查找foo(1)这个字符串, 但如果按照正则表达式来解释,被查找的对象就成了 foo1 了。
于是,vim就规定,正则表达式的元字符必须用反斜杠进行转义才行, 如上面的例子,如果确实要用正则表达式,就应当写成 /foo\(1\) 。 但是,像 . * 这种极其常用的元字符,都加上反斜杠就太麻烦了。 而且,众口难调,有些人喜欢用正则表达式,有些人不喜欢用……
为了解决这个问题,vim设置了 magic 这个东西。简单地说, magic就是设置哪些元字符要加反斜杠哪些不用加的。 简单来说:
- magic(\m):除了 $ . * ^ 之外其他元字符都要加反斜杠。
- nomagic(\M):除了 $ ^ 之外其他元字符都要加反斜杠。
这个设置也可以在正则表达式中通过 \m \M 开关临时切换。 \m 后面的正则表达式会按照 magic 处理,\M 后面的正则表达式按照 nomagic 处理, 而忽略实际的magic设置。
例如:
/\m.* # 查找任意字符串 /\M.* # 查找字符串 .* (点号后面跟个星号)
另外还有更强大的 \v 和 \V。
- \v(即 very magic 之意):任何元字符都不用加反斜杠
- \V(即 very nomagic 之意):任何元字符都必须加反斜杠
例如:
/\v(a.c){3}$ # 查找行尾的abcaccadc
/\m(a.c){3}$ # 查找行尾的(abc){3}
/\M(a.c){3}$ # 查找行尾的(a.c){3}
/\V(a.c){3}$ # 查找任意位置的(a.c){3}$
默认设置是 magic,vim也推荐大家都使用magic的设置,在有特殊需要时,直接通过 \v\m\M\V 即可。
本文下面使用的元字符都是 magic 模式下的。
量词
vim的量词与perl相比一点也不逊色。
| vim | Perl | 意义 |
| * | * | 0个或多个(匹配优先) |
| \+ | + | 1个或多个(匹配优先) |
| \? 或 \= | ? | 0个或1个(匹配优先),\?不能在 ? 命令(逆向查找)中使用 |
| \{n,m} | {n,m} | n个到m个(匹配优先) |
| \{n,} | {n,} | 最少n个(匹配优先) |
| \{,m} | {,m} | 最多m个(匹配优先) |
| \{n} | {n} | 恰好n个 |
| \{-n,m} | {n,m}? | n个到m个(忽略优先) |
| \{-} | *? | 0个或多个(忽略优先) |
| \{-1,} | +? | 1个或多个(忽略优先) |
| \{-,1} | ?? | 0个或1个(忽略优先) |
从上表中可见,vim的忽略优先量词不像perl的 *? +? ?? 那样,而是统一使用 \{- 实现的。 这大概跟忽略优先量词不常用有关吧。
环视和固化分组
vim居然还支持环视和固化分组的功能,强大,赞一个
关于环视的解释请参考Yurii的《精通正则表达式》一书吧。
| vim | Perl | 意义 |
| \@= | (?= | 顺序环视 |
| \@! | (?! | 顺序否定环视 |
| \@<= | (?<= | 逆序环视 |
| \@<! | (?<! | 逆序否定环视 |
| \@> | (?> | 固化分组 |
| \%(atom\) | (?: | 非捕获型括号 |
和perl稍有不同的是,vim中的环视和固化分组的模式的位置与perl不同。 例如,查找紧跟在 foo 之后的 bar,perl将模式写在环视的括号内, 而vim将模式写在环视的元字符之前。
# Perl的写法 /(?<=foo)bar/ # vim的写法 /\(foo\)\@<=bar
参考
vim的帮助文件非常有用,关于正则表达式可以参考以下的内容。
:h pattern :h magic :h perl-patterns
最近Firefox的行为很奇怪,出现了许多以前一直没见过的现象。回想一下似乎是升级了delicious bookmarks 2.0.58版导致的。
目前发现的问题如下:
- 历史菜单内的前进、后退按钮失效,工具栏的前进、后退、刷新按钮失效,右键菜单中相应菜单也失效,但用快捷键和鼠标手势可以正常浏览;
- 不论访问什么网页,地址栏总是显示第一次手工输入的地址,而不会随着当前页面的变化而更新;
- Ctrl-Tab切换Tab时,松手后屏幕中间显示的切换菜单不会自动消失;
- 按一下Ctrl-Tab无法在所有Tab中依次切换,只能在当前Tab和上一个Tab之间切换;
- Ctrl-PageUp和Ctrl-PageDown的功能会反过来,即Ctrl-PageUp变成“下一个Tab”,而Ctrl-PageDown变成“上一个Tab”。
这些现象在禁用delicious bookmarks后消失。但delicious bookmarks又不能不用,于是卸载之后从官方插件站点上重新安装了一次,目前还未发生上述问题。
2008-6-20更新:
今天delicious bookmarks 2.0.64版发布了,更新内容包括:
This release fixes several issues with FF2 and FF3 GA.
- Fixes for "Organize Bookmarks" performance on FF3
- Fixes for strange tab behavior in FF2
- Fixes for sync issues on startup and login
- Removing status bar icons now frees up space on the status bar
- Classic mode has been simplified to remove the Delicious menu and work via bookmarklet interface
- Cleaned up Delicious Bookmarks Options UI
其中第二条就是解决标签切换行为异常的。
很短很好用,不过自己老是忘,干脆写下来吧。
当你有一大篇文字,没有换行(或者行宽太宽、太窄),并且段落之间用空行分开, 那么可以使用以下的技巧来重新分行。
:set tw=100 " textwidth,设置文本行宽度 :set fo+=mM " formatoptions,设置自动换行的条件 gggqG
用过之后第一感觉:太强大了,让那些商业的共享的软件都去死吧!
AviSynth,可以进行视频合成、编辑、添加字幕,支持所有格式(只要能播放出来), 甚至可以将图片转换为视频。
AviSynth的原理是通过一个脚本,将视频流、音频流处理之后再以流的方式输出。 输出流可以通过播放器直接播放,也可以利用ffmpeg、 VirtualDub等软件将流保存为各种视频格式。 而正是强大的脚本使它具有了强大了视频处理能力。
阅读全文 »相信有很多人都想架设自己的DNS服务器。我们知道世界上最好用的DNS服务器软件就是BIND; 但是我辈使用Windows操作系统的人就无福享用这Unix下的顶级软件了。
或者可以用Windows Server自带的DNS服务器试试? 需要安装Server版的Windows不说,麻烦的配置和令人迷惑的图形界面就够受的了。
难道就没有一个解决方案了吗?
柳暗花明又一村,突然发现BIND居然有Windows版,这这这………… 赶快下载下来试一下,居然成功地配好了DNS。
阅读全文 »昨天因为要将相机拍摄的视频刻录成VCD,于是上网找了好多MPEG的相关工具, 如切割、合并、格式转换等,大部分都是共享软件并且还有功能限制。 后来实在没办法了,想到了ffmpeg这个工具,抱着试试看的心情看了看帮助, 才发现原来真正的工具在这里!支持绝大多数常见的视频音频格式, 可以在各种格式之间随意转换,支持视频切割。所以说,真正好用的东西其实都是免费的。
ffmpeg的命令行格式如下:
ffmpeg [输入参数] -i 输入文件 [输出参数] 输出文件
这里仅举几个我用到的例子。
截取1分30秒到1分50秒的视频,格式不变。-ss指定起始时间,-t指定截取长度,-vcodec 和-acodec指定为copy表明不对源视频音频流做任何处理直接复制。
ffmpeg -ss 0:1:30 -t 0:0:20 -i input.mpg -vcodec copy -acodec copy output.mpg
mpg转换成vcd所用的视频格式。-ac 2表示将单声道音频转换成立体声。
ffmpeg -i input.mpg -target pal-vcd -ac 2 output.mpg
VCD要求视频大小为 352x240,而我们的视频大小为320x240,需要在两边加上黑边凑足352像素:
ffmpeg -i input.mpg -padleft 16 -padright 16 -padcolor 000000 -target pal-vcd -ac 2 output.mpg
将字幕合并到视频中,可以利用AviSynth,首先制作好srt格式字幕, 然后利用DIO's RelProducer GUI加载视频和字幕生成avs文件,再利用ffmpeg转换此avs文件:
ffmpeg -i input.avs output.mpg
合并视频流和音频流,可以先利用ffmpeg将mp3转换成wav:
ffmpeg -i input.mp3 output.wav
然后再利用VirtualDub合并之。
这一篇是扫盲用的,主要讲解了几个最常用的函数IF、AND、OR、COUNT、COUNTA、COUNTIF和SUM, 会用的同学就可以跳过了。以后会逐渐讲解其他函数的应用。
1. 逻辑判断
逻辑判断所用的函数不多,IF、AND、OR三个就足以应付日常工作了。
IF函数可以用来转换值,如将1和0转换为OK和NG:
=IF(A1=1,"OK","NG")
与AND和OR组合使用可以判断多个条件,如判断是否是周末:
=IF(OR(WEEKDAY(A1)=0, WEEKDAY(A1)=6),"周末","工作日")
2. 统计数量的COUNT、COUNTA、COUNTIF
COUNT和COUNTA统计对象不同,COUNTA统计所有非空单元格的数量(包括出错的单元格), COUNT仅统计看起来像数字的单元格。
COUNTIF则可以添加搜索条件,这个特性可以用来做统计。如
=COUNTIF(F:F,"OK") 统计F列中OK的个数 =COUNTIF(F:F,"NG") 统计F列中NG的个数
3. 求和的SUM
这个函数简单得不能再简单了:
=SUM(A10:A254) 对A10~A254的范围求和
没了。别看Excel函数成百上千,常用的就这几个。充其量再加上其他几个信息函数, 如求日期的DATE、YEAR、MONTH、DAY、NOW、WEEKDAY,数值计算的FLOOR、INT、MOD、ROUND, 字符串操作的CHAR、LEFT、RIGHT、MID(具体使用方法参见帮助), 几乎可以应付全部的日常应用。
下面举几个例子来说明这些函数的应用。
1. 测试用例。一般测试用例的表格会是这样:
| A | B | C | D | E | F | |
| 1 | 编号 | 类别 | 测试内容 | 确认内容 | 结果 | 测试时间 |
| 2 | 1 | 界面 | 单击新建按钮 | 建立新文档 | OK | 8/27 |
| 3 | 2 | 界面 | 单击保存按钮 | 保存文档 | OK | 8/27 |
| 3 | 2 | 界面 | 单击另存为钮 | 打开保存对话框 | NG | 8/27 |
那么统计OK和NG的个数就分别用
=COUNTIF(E:E,"OK") 统计OK个数 =COUNTIF(E:E,"NG") 统计NG个数
如果测试用例分成好几个工作表,那么可以在最前面加一个统计用的工作表,并用SUM求出所有用例的状况。
2. 日历。这个日历是用在项目进度管理上的,格式类似于下面这种横向的日历。
| 8月 | ||||||||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 三 | 四 | 五 | 六 | 日 | 一 | 二 | 三 | 四 | 五 | 六 |
可按以下格式输入:
| A | B | C | D | E | F | G | |
| 1 | 8/1 | =A1+1 | =B1+1 | ... | ... | ... | ... |
| 2 | =MONTH(A1) | =IF(MONTH(B1)=MONTH(A1), "",MONTH(B1) | ... | ... | ... | ... | ... |
| 3 | =DAY(A1) | =DAY(B1) | ... | ... | ... | ... | ... |
| 4 | =MID("日一二三四五六",WEEKDAY(A1),1) | ... | ... | ... | ... | ... | ... |
然后隐藏掉第一行即可。
2008-2-14更新 回答读者妮妮的问题,讲解一下VLOOKUP函数的用法。
VLOOKUP用于查找信息,更确切地说,它用来“翻译”信息。比如员工名单上有员工号和姓名的对应关系, 那么给出一个员工号的列表,就可以通过VLOOKUP将其“翻译”成姓名列表。先来看个例子:
| A | B | C | D | |
| 1 | 排行 | 姓名 | 排行 | 姓名 |
| 2 | 1 | 柯镇恶 | 3 | =VLOOKUP(C2,$A$2:$B$8,2) |
| 3 | 2 | 朱聪 | 3 | =VLOOKUP(C3,$A$2:$B$8,2) |
| 4 | 3 | 韩宝驹 | 4 | =VLOOKUP(C4,$A$2:$B$8,2) |
| 5 | 4 | 南希仁 | 7 | =VLOOKUP(C5,$A$2:$B$8,2) |
| 6 | 5 | 张阿生 | ||
| 7 | 6 | 全金发 | ||
| 8 | 7 | 韩小莹 |
这个表的$A$2:$B$8区域为参考数据(原始对应关系),C列为需要翻译的原始数据,D列为翻译结果。 具体的结果大家可以实际放到Excel里面执行一下。
VLOOKUP有三个参数,分别如下:
VLOOKUP(原始数据, 参考数据, 搜索结果在参考数据中的列位置)
Excel会在参考数据的第一列中搜索原始数据(上例中,在$A$2:$B$8的第一列即$A$2:$A$8中搜索原始数据C2), 找到后,返回第三个参数——列位置所对应的数据(上例中,在$A$2:$A$8中找到与C2相等的3之后, 返回3所对应的第2列——韩宝驹,这个“第2列”即为第三个参数)。
那么找不到时怎么办?其实VLOOKUP还有第四个参数,值为TRUE或FALSE,默认为TRUE。 取值TRUE时,VLOOKUP会返回不大于原始数据的最小值所对应的结果,例如=VLOOKUP(2.5,$A$2:$B$8,2,TRUE)会返回“朱聪” (朱聪的“2”为不大于2.5的最大值)。 取值为FALSE时,VLOOKUP会返回#N/A。
通常在处理字符串时,大多情况下希望在找不到时返回错误或空串。 这时可以为VLOOKUP加上第四个参数FALSE,再用ISNA函数将#N/A转换为空串。如:
[D2]=VLOOKUP(C2,$A$2:$B$8,2,FALSE) [D3]=IF(ISNA(D2),"",D2)
