日志更新

折翼的天使



静静的
趴在你的背上
亲吻着那
深深的伤痕
我的天使


泪水交织着
早已不在的羽翼
只为爱情
却藏着
美人鱼秘密的痛
陪伴在
属于我的世界


不知
前世的承诺
今世要做我的天使


幼稚的我
诉说着痴恋
要你带我飞翔
你哭了
每天的羽毛
换来彼此的相依
只为那前世的梦


你说
我是折翼的天使
永远无法带你翱翔
充满流星的夜
再也回不了天堂


心痛着
含着点点泪
亲吻那逝去的翅膀
祈盼着来世
折下为你飞翔

哥俩好:oninput & onpropertychange

传统对于文本框(input)的输入可通过键盘的 onkeydown / onkeypress / onkeyup 来监测,但在处理较多细节时存在诟病比如: cut(剪切) / paste(复制) / undo(撤销) / redo(重做) / drag & drop(拖拽)/ 输入法等。

而 oninput & onpropertychange 事件基本可以解决上面的诟病:

oninput 事件作为 HTML5 中的标准事件,基本除了IE6 / IE7 / IE8 外的最新浏览器均支持(注:1、原先的 Opera 的虽支持,但依然存在部分传统的诟病,从 Opera 11+ 开始,已修复,更加完美;2、IE9 也支持)。

function(input, callback){
    if ("onpropertychange" in input) { //IE6/IE7/IE8
        input.onpropertychange = function(){
            if (window.event.propertyName == "value"){
                callback.call(this, window.event)
            }
        }
    } else {
        // Fix Firefox Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=195696
        input.addEventListener("input", callback, false);
    }
}

提示:

  1. oninput 事件:当 JS 改变 value 值或从浏览器的自动下拉提示中选值时,不会触发。
  2. onpropertychange 事件:当 input 设置为不可用(disable=true)时,不会触发。

参考文章:

将字符实体引用转换成 Unicode 字符

首先我们一起来看下 Character entities references (HTML Entities)和 Numeric Character Reference (NCR)的异同:

HTML Entities 的格式如:&lt;,NCR 的格式如:&#60;&#x3c;,均都表示“<” 字符。

HTML 中规定了 Character entity references,在 “24.2.1 The list of characters” 列出了 HTML Entities 和 NCR 的对应关系,例如:

<!ENTITY nbsp   CDATA "&#160;" -- no-break space = non-breaking space, U+00A0 ISOnum -->
<!ENTITY iexcl  CDATA "&#161;" -- inverted exclamation mark, U+00A1 ISOnum -->
<!ENTITY yen    CDATA "&#165;" -- yen sign = yuan sign, U+00A5 ISOnum --> 

那在 Python 中我们如何将 HTML Entities 和 NCR 转换成普通字符呢?

在回答这个问题之前,我们做一些简单的回顾:

group 方法

group([group1,…]) 

group 属于 Match Object 对象拥有的方法,返回匹配到的一个或者多个子组。如果是一个参数,那么结果返回字符串,如果是多个参数,则返回元组。group1 的默认值为 0 (将返回所有的匹配值),如果 groupX 的值是 [1…99] 范围之内的,那么将匹配对应括号组的字符串。如果组号是负的或者比 pattern 中定义的组号大,那么将抛出 IndexError 异常。若 pattern 没有匹配到,但 group 匹配到,那么 group 的值也为 None。如果一个 pattern 可以匹配多个,那么组对应匹配的最后一个。

re.sub 方法

re.sub(pattern , replace , string [, count])

sub 属于 re 模块的字符串替换和修改函数,其在目标字符串中查找与正则相匹配的字符串,并将其替换成指定的字符串。

  • pattern 参数——需要匹配的正则规则
  • replace 参数——指定用来替换的字符串或函数。如果 replace 是函数,则会对所有的匹配都回调此函数,这个函数使用单个 Match Object 作为参数,然后返回替换后的字符串。
  • string 参数——目标字符串
  • count 参数——最多替换的次数,未指定,则将替换所有匹配到的字符串

re.sub() 的使用案例如下:

import re
def dashrepl(matchobj):
    if matchobj.group(0) == '-':
        return ' '
    else:
        return '-'
re.sub('-{1,2}', dashrepl, 'pro----gram-files')

# result: 'pro--gram files'

htmlentitydefs

htmlentitydefs 有三个属性,详细如下:

  • entitydefs:A dictionary mapping XHTML 1.0 entity definitions to their replacement text in ISO Latin-1.
  • name2codepoint:A dictionary that maps HTML entity names to the Unicode codepoints. New in version 2.3.
  • codepoint2name:A dictionary that maps Unicode codepoints to HTML entity names.

实际存在的形式大致如下:

entitydefs = {'AElig': '\xc6', 'Aacute': '\xc1', 'Acirc': '\xc2', ...}
name2codepoint = {'AElig': 198, 'Aacute': 193, 'Acirc': 194, ...}
codepoint2name = {34: 'quot', 38: 'amp', 60: 'lt', 62: 'gt', ...}

对于我们来说,此时最有用的是 name2codepoint 属性,比如:“<”,name 是 lt,我们可以通过 name2codepoint[lt] 获得其 code point:60。

unichr 方法

unichr 是字符串的方法(unichr(int)),可以将整数转化成相应的 Unicode 字符,比如: unichr(60) –> u'\u003c' or u'<'

import re, htmlentitydefs

##
# Removes HTML or XML character references and entities from a text string.
#
# @param text The HTML (or XML) source text.
# @return The plain text, as a Unicode string, if necessary.

def unescape(text):
    def convert(matchobj):
        text = matchobj.group(0)
        if text[:2] == "&#":
            # Numeric Character Reference
            try:
                if text[:3] == "&#x":
                    return unichr(int(text[3:-1], 16))
                else:
                    return unichr(int(text[2:-1]))
            except ValueError:
                pass
        else:
            # Character entities references
            try:
                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
            except KeyError:
                pass
        return text # Return Unicode characters
    return re.sub("&#?\w+;", convert, text)

扩展阅读:

使用 JScript 创建 .exe 或 .dll 文件

什么是 JScript?

JScript 是由微软开发的活动脚本语言,基于 ECMAScript 规范实现。Internet Explorer 中的 JavaScript,实际上是指 JScript。JScript 已被 Windows Script Host(WSH)支持(WSH 中的 JavaScript shell scripting:C:\> cscript jslint.js)。JScript 最新的版本(JScript.NET)基于 ECMAScript 4.0 ,并且可以在 .Net 环境下编译。

.NET Framwork 中包含有 JScript 编译器 :JScriptCompiler (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\jsc.exe),其可以将 JScript 文件编译为一个 .exe 或者 .dll 文件。

为了方便使用,我们可以将 JScriptCompiler 的路径加入到环境变量(环境变量 –> 系统变量 –> Path)中。在 CMD 程序运行窗口中直接调用命令 “jsc”,就可以看到编译器相关的帮助选项。

jsc [选项] <源文件> [[选项] <源文件>…]

JScript 编译器选项

– 输出文件 -
/out:<file> 指定二进制输出文件的名称
/t[arget]:exe 创建控制台应用程序(默认)
/t[arget]:winexe 创建 Windows 应用程序
/t[arget]:library 创建库程序集
/platform:<platform> 限制此代码可以在其上运行的平台;必须是 x86、Itanium、x64 或 anycpu。默认为 anycpu

– 输入文件 -
/autoref[+|-] 基于导入的命名空间和完全限定名称自动引用程序集(默认情
况下为 on)
/lib:<path> 指定要在其中搜索引用的附加目录
/r[eference]:<file list> 从指定的程序集文件引用元数据 <file list>: <assembly name>[;<assembly name>...]

– 资源 -
/win32res:<file> 指定 Win32 资源文件(.res)
/res[ource]:<info> 嵌入指定的资源 <info>: <filename>[,<name>[,public|private]]
/linkres[ource]:<info> 将指定的资源链接到此程序集 <info>: <filename>[,<name>[,public|private]]

– 代码生成 -
/debug[+|-] 发出调试信息
/fast[+|-] 禁用语言功能以使代码更好地生成
/warnaserror[+|-] 将警告视为错误
/w[arn]:<level> 设置警告等级(0-4)

– 杂项 -
@<filename> 有关更多选项,请阅读响应文件
/? 显示帮助
/help 显示帮助
/d[efine]:<symbols> 定义条件编译符号
/nologo 不显示编译器版权标志
/print[+|-] 提供 print() 函数

– 高级 -
/codepage:<id> 使用指定的代码页 ID 打开源文件
/lcid:<id> 将指定的 LCID 用于消息和默认代码页
/nostdlib[+|-] 不导入标准库(mscorlib.dll)并将 autoref 默认值更改为 off
/utf8output[+|-] 以 UTF-8 字符编码形式发出编译器输出
/versionsafe[+|-] 为没有标记为“override”或“hide”的成员指定默认值

创建 .exe 文件

先创建 JS 文件(C:\test\helloWorld.js),内容如下:

var date = new Date();
print('Hello World! \nToday is ' + date );

接着我们进行编译:

C:\test>jsc helloWorld.js

Microsoft (R) JScript Compiler version 8.00.50727
for Microsoft (R) .NET Framework version 2.0.50727
Copyright (C) Microsoft Corporation 1996-2005。保留所有权利。

你会惊讶的发现,C:\test 目录下多了个 helloWorld.exe 文件,非常简单吧,呵呵

最后我们可以直接执行 helloWorld.exe 文件:

C:\test>helloWorld

Hello World!
Today is Fri Jun 3 23:13:20 UTC+8 2011

大功告成!!

创建 .dll 文件

.dll 文件的创建也同样非常简单:

package LibHW {
    class HelloWorld {
        function run() {
            var date = new Date();
            return 'Hello World! \nToday is ' + date;
        }
    }
}

编译语句:

C:\test>jsc /t:library LibHW.js

对于生成的 LibHW.dll 文件,我们可以通过创建新的 .exe 文件(consumer.js –> consumer.exe)以导入模块的方式调用(类似于 Python)。

先创建 consumer.js 文件:

import LibHW;
var hw = new LibHW.HelloWorld();
print(hw.run());

然后编译 consumer.js 文件,执行 consumer.exe:

C:\test>jsc consumer.js

Microsoft (R) JScript Compiler version 8.00.50727
for Microsoft (R) .NET Framework version 2.0.50727
Copyright (C) Microsoft Corporation 1996-2005。保留所有权利。

C:\test>consumer

Hello World!
Today is Sat Jun 4 00:42:35 UTC+8 2011

当然你还可以创建 windows 的应用,上例中的 consumer.js 文件修改如下:

import System.Windows.Forms; // this has a MessageBox class
import LibHW;

var hw = new LibHW.HelloWorld();
MessageBox.Show(
    hw.run(),
    "Dude!",
    MessageBoxButtons.OK,
    MessageBoxIcon.Exclamation
);

编译语句:

C:\test>jsc /t:winexe consumer.js

双击新生成的 consumer.exe 文件,哈哈,是不是很有成就感!

从上面的例子可以看到 JScript 的潜力无限,没有做不到,只有想不到。

扩展阅读: