全半角字符互相转换

供新手入门和老手参考的教程和相关资料,包括中文帮助

Moderators: tmplinshi, arcticir

User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

全半角字符互相转换

24 Aug 2014, 21:02

导言:这类文章似乎是给大家提供实用的脚本,实际上你不一定用的上(100 人中有几个需要可能都很多了),至少并非马上需要,而我真正想告诉大家的是我是如何写脚本的。因此,本文中这些脚本的用途只是赠品,希望大家阅读时不要买椟还珠。
我曾说过,要写出好脚本需要有清晰的思路,如何做到这点呢?有两个基本前提:
  • 对 AutoHotkey 自身命令、函数及其用法十分熟悉,例如看到问题中需要按一定规则调整顺序时立即想到 Sort 命令。这是在编写过一定数量的脚本后形成的自然反应。这是基础。
  • 深入观察目标任务,尽可能了解其各方面特点,并从中提取有用的信息应用于脚本。这点不详细解释,请从后面两段代码的不同思路上体会。
linpinger 的实现
linpinger wrote:之前使用的是用stringreplace一个个的替换,不过这样会有乱码的产生
因为某些中文字的Ascii码是这样的, 类似: 丵 (0x8151),一般的中文字符类似: 好(0xbac3),前面字符的Ascii值都大于128,后面的也大于128,个别例外,后半部分小于128, 丵 就是例子,这样使用 stringreplace 的时候,可能将 丵 字的后半部分也替换为中文字符,这样从这个字开始就出现乱码了,所以偶改进了一下转换方式,一个字符一个字符的来判断,这样乱码问题应该能避免了
注:linpinger 当时使用的是 AutoHotkey Basic,所以 StringReplace 替换时会出现乱码,此问题在 AutoHotkey_L 中已不存在。

Code: Select all

K3_StrBJ2QJ(byref srcnr, byref tarnr) ; 注意初始化tarnr,新半角转全角,每个字符分析,理论上正常
{
    isSecond := 0
    loop, parse, srcnr
    {
        If isSecond
            tarnr .= A_Loopfield , isSecond := 0
        else { ; 非第二个字符
            NowAscii := asc(A_Loopfield)
            If ( NowAscii > 128 )
                tarnr .= A_Loopfield , isSecond := 1
            else {
                If ( NowAscii > 32 )
                    tarnr .= K3_CharBJ2QJ(NowAscii)
                else
                    tarnr .= A_loopfield
            }
        }
    }
}

K3_CharBJ2QJ(AsciiNum=97) ; 单个字符转换为全角
{
    static Ascii_33 := "!" , Ascii_34 := """ , Ascii_35 := "#" , Ascii_36 := "$" , Ascii_37 := "%" , Ascii_38 := "&" , Ascii_39 := "'" , Ascii_40 := "(" , Ascii_41 := ")" , Ascii_42 := "*" , Ascii_43 := "+" , Ascii_44 := "," , Ascii_45 := "-" , Ascii_46 := "." , Ascii_47 := "/" , Ascii_48 := "0" , Ascii_49 := "1" , Ascii_50 := "2" , Ascii_51 := "3" , Ascii_52 := "4" , Ascii_53 := "5" , Ascii_54 := "6" , Ascii_55 := "7" , Ascii_56 := "8" , Ascii_57 := "9" , Ascii_58 := ":" , Ascii_59 := ";" , Ascii_60 := "<" , Ascii_61 := "=" , Ascii_62 := ">" , Ascii_63 := "?" , Ascii_64 := "@" , Ascii_65 := "A" , Ascii_66 := "B" , Ascii_67 := "C" , Ascii_68 := "D" , Ascii_69 := "E" , Ascii_70 := "F" , Ascii_71 := "G" , Ascii_72 := "H" , Ascii_73 := "I" , Ascii_74 := "J" , Ascii_75 := "K" , Ascii_76 := "L" , Ascii_77 := "M" , Ascii_78 := "N" , Ascii_79 := "O" , Ascii_80 := "P" , Ascii_81 := "Q" , Ascii_82 := "R" , Ascii_83 := "S" , Ascii_84 := "T" , Ascii_85 := "U" , Ascii_86 := "V" , Ascii_87 := "W" , Ascii_88 := "X" , Ascii_89 := "Y" , Ascii_90 := "Z" , Ascii_91 := "[" , Ascii_92 := "\" , Ascii_93 := "]" , Ascii_94 := "^" , Ascii_95 := "_" , Ascii_96 := "`" , Ascii_97 := "a" , Ascii_98 := "b" , Ascii_99 := "c" , Ascii_100 := "d" , Ascii_101 := "e" , Ascii_102 := "f" , Ascii_103 := "g" , Ascii_104 := "h" , Ascii_105 := "i" , Ascii_106 := "j" , Ascii_107 := "k" , Ascii_108 := "l" , Ascii_109 := "m" , Ascii_110 := "n" , Ascii_111 := "o" , Ascii_112 := "p" , Ascii_113 := "q" , Ascii_114 := "r" , Ascii_115 := "s" , Ascii_116 := "t" , Ascii_117 := "u" , Ascii_118 := "v" , Ascii_119 := "w" , Ascii_120 := "x" , Ascii_121 := "y" , Ascii_122 := "z" , Ascii_123 := "{" , Ascii_124 := "|" , Ascii_125 := "}" , Ascii_126 := "~"
    return, Ascii_%AsciiNum%
}
amnesiac 的实现
刚开始想到这个问题时,我想到使用类似映射表来实现,经过观察字符编码的关系后,发现可以用很简单方法实现。

Code: Select all

InputBox, Key, 输入框, 请输入要转换成全角的字符
MsgBox, % Key ":" HalfShape4FullShape(Key, true)
return
所需函数:

Code: Select all

/*
HalfShape4FullShape()
        全角半角字符互相转换函数。需要 AutoHotkey_L Unicode 版本。
作者: amnesiac
参数说明:
        Char        需转换的字符。
        ToFullShape        为真时转换为全角,否则转换为半角。
*/
HalfShape4FullShape(Char, ToFullShape = true)
{
        if ToFullShape && (Asc(Char) < 256) && Asc(Char)
                return, Chr(Asc(Char) + 65248)
        else if !ToFullShape && (Asc(Char) < 65504) && (Asc(Char) > 65248)
                return, Chr(Asc(Char) - 65248)
        else
                return, Char
}
现在你知道我发现了什么?
小结
转换类问题,主要思路有两种:
  • 使用 StringReplace/RegexReplace 直接替换,一般适用于有限数目的替换;
  • 通过映射关系替换,有两种情况:
    • 能够在内部获取映射关系实现替换,如字符与编码的转换;
    • 需自行构造或从外部文件获取映射关系查表替换,如本文中 linpinger 的脚本。
在我的脚本中利用了全半角字符编码相差 65248 的原理,这是深入观察的结果,所以转换起来就简单多了。
AutoHotkey 学习指南(Beauty of AutoHotkey)
I do not make codes, and only a porter of AutoHotkey: from official to Chinese, from other languages to AutoHotkey, and show AutoHotkey to ordinary users sometimes.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 全半角字符互相转换

25 Aug 2014, 07:24

好用!
User avatar
huyaowen
Posts: 109
Joined: 28 Jul 2014, 01:15

Re: 全半角字符互相转换

25 Aug 2014, 22:10

好用!

Return to “教程资料”

Who is online

Users browsing this forum: No registered users and 13 guests