您正在从Perl 5.6.2查看此文档的版本。查看最新版本

目录

名称

perlebcdic-在EBCDIC平台上运行Perl的注意事项

说明

探讨基于EBCDIC的计算机上Perl程序员面临的一些问题。我们还没有讨论本地化、国际化或多字节字符集问题。

仍不完整的部分用XXX标记。

通用字符代码集

ASCII码

美国信息交换标准代码是一组从0到127(十进制)的整数,表示显示器和其他计算机系统可以解释字符。通过将位设置为7位二进制数字,可以覆盖范围0..127,因此该集合有时被称为“7位ASCII”。美国国家标准协会文件ANSI X3.4-1986对ASCII进行了描述。ISO 646:1991也对其进行了描述(货币符号本地化)。下表中给出了完整的ASCII集合,作为前128个元素。可以用ASCII字符充分书写的语言包括英语、夏威夷语、印尼语、斯瓦希里语和一些美洲土著语言。

有许多字符集可以将整数范围从0..2**7-1扩展到2**8-1或8位字节(如果愿意,可以使用八位字节)。一个常见的是ISO 8859-1字符集。

ISO 8859标准

ISO 8859-$n是来自国际标准化组织(ISO)的字符代码集的集合,每个字符都将字符添加到ASCII集合中,ASCII集合通常在欧洲语言中出现,其中许多语言基于罗马或拉丁字母表。

拉丁语1(ISO 8859-1)

ASCII的一种特殊的8位扩展,包括重音和锐音拉丁字符。可以使用ISO 8859-1的语言包括ASCII涵盖的所有语言以及南非荷兰语、阿尔巴尼亚语、巴斯克语、加泰罗尼亚语、丹麦语、法罗群岛语、芬兰语、挪威语、葡萄牙语、西班牙语和瑞典语。尽管没有ij结扎,但荷兰语仍被覆盖。法语也被覆盖,但没有oe结扎。德语可以使用ISO 8859-1,但必须在没有德语引号的情况下使用。此集合基于ASCII的西欧扩展,在全球网络工作中常见。在IBM字符代码集标识术语ISO 8859-1中也称为CCSID 819(有时为0819,甚至00819)。

EBCDIC公司

扩展二进制编码十进制交换码是指与ASCII或ISO 8859-1不同的、通常在主机上运行的、稍有不同的单字节和多字节编码字符集的大集合。EBCDIC编码源自霍尔瑞斯穿孔卡编码的8位字节扩展。卡片上的布局是这样的,为大小写字母字符[a-z]和[a-z]设置了高位,但每个拉丁字母范围内都有空白。

某些IBM EBCDIC字符集可以通过字符代码集标识号(CCSID号)或代码页号来识别。本文档中CCSID编号的前导零位数字无关紧要。例如,CCSID 0037在某些地方可以称为37。

13个变体字符

在IBM EBCDIC字符代码集中,有13个字符通常映射到不同的整数值。这些字符被称为13个“变体”字符,它们是:

\ [ ] { } ^ ~ ! # | $ @ `

0037

字符代码集ID 0037是ASCII加拉丁文-1字符(即ISO 8859-1)到EBCDIC集的映射。0037用于在AS/400计算机上运行的OS/400操作系统上的北美英语地区。CCSID 37在237处与ISO 8859-1不同,换句话说,它们只同意19个代码点值。

1047

字符代码集ID 1047也是ASCII加拉丁文-1字符(即ISO 8859-1)到EBCDIC集的映射。1047在Unix System Services for OS/390和OpenEdition for VM/ESA下使用。CCSID 1047与CCSID 0037在八处不同。

POSIX-BC公司

西门子BS2000系统上使用的EBCDIC代码页与1047和0037不同。以下将其标识为POSIX-BC集合。

单八分位表格

下表列出了ASCII和拉丁语1有序集,包括子集:C0控件(0..31)、ASCII图形(32..7e)、删除(7f)、C1控件(80.9f)和拉丁语-1(也称为ISO 8859-1)(a0..ff)。在表中,非打印控制字符名以及ASCII的拉丁文1扩展名被标记为大致对应于Unicode标准2.0版尽管在所有情况下都有替换,例如s/LATIN//和s/VULGAR//,在某些情况下是s/CAPITAL LETTER//,在其他情况下是s/SMALL LETTER([A-Z])/\l$1/字符名遗憾的是,杂注名称没有列出C0或C1控制字符的显式名称)。此处列出的C1控制集(ISO 8859-1中的128..159)的“名称”有些随意。0037和1047集合之间的差异用***标记。1047和POSIX-BC集合之间的差异用###标记。列出的所有ord()数字均为十进制。如果您希望看到此表列出八进制值,请通过以下方式运行该表(即此文档的pod版本,因为此配方可能无法与pod2_other_format转换一起使用):

配方0
perl-ne'如果(/(.{33})(\d+)\s+(\d+)\s+\-e'{printf(“%s%-9o%-9o%-9o%-90%-9o\n”,$1,$2,$3,$4,$5)}'perlebcdic.pod

如果您希望看到此表列出十六进制值,请运行该表:

配方1
perl-ne'如果(/(.{33})(\d+)\s+(\d+)\s+\-e'{printf(“%s%-9X%-9X%-9X%-9X-9X\n”,$1,$2,$3,$4,$5)}'perlebcdic.pod8859-1chr 0819 0037 1047 POSIX-BC公司----------------------------------------------------------------<NULL>0 0 0 0<标题开始>1 1 1 1<文本开头>2 2 2 2<文本结尾>3 3 3 3<传输结束>4 55 55 55<询问>5 45 45 45<确认>6 46 46 46<贝尔>7 47 47 47 47<退格>8 22 22 22<水平表格>9 5 5 5<线路馈线>10 37 21 21***<垂直表格>11 11 11 11<表单馈送>12 12 12 12<托架返回>13 13 13 13<移出>14 14 14 14<移入>15 15 15 15<数据链路退出>16 16 16 16<设备控制一>17 17 17 17<设备控制二>18 18 18 18<设备控制三>19 19 19 19<设备控制四>20 60 60 60 60<否定承认>21 61 61 61<同步怠速>22 50 50 50<传输块结束>23 38 38 38<取消>24 24 24 24<介质结束>25 25 25 25<替代>26 63 63 63<逃离>27 39 39 39<文件分离器>28 28 28 28<分组分离器>29 29 29 29<记录分离器>30 30 30 30<单元分离器>31 31 31 31<空格>32 64 64 64!                            33       90       90       90"                            34       127      127      127#                            35       123      123      123$                            36       91       91       91%                            37       108      108      108&                            38       80       80       80'                            39       125      125      125(                            40       77       77       77)                            41       93       93       93*                            42       92       92       92+                            43       78       78       78,                            44       107      107      107-                            45       96       96       96.                            46       75       75       75/                            47       97       97       970                            48       240      240      2401                            49       241      241      2412                            50       242      242      2423                            51       243      243      2434                            52       244      244      2445                            53       245      245      2456                            54       246      246      2467                            55       247      247      2478                            56       248      248      2489                            57       249      249      249:                            58       122      122      122;                            59       94       94       94<                            60       76       76       76=                            61       126      126      126>                            62       110      110      110?                            63       111      111      111@                            64       124      124      124A 65193193 193B 66194194 194C 67 195 195 195D 68 196 196 196电子69 197 197 197传真:70198198198G 71 199 199 199H 72 200 200 200型我73 201 201 201J 74 209 209 209K 75 210 210 210电话电话76 211 211 211电话:77 212 212 212N 78 213 213 218号O 79 214 214 215电话电话:80 215 215 2150问81 216 216 21882217217 217兰特S 83 226 226 227编号电话84227227 227U 85 228 228 222电话V 86 229 229 228伏宽87 230 230 230X 88 231 231 231Y 89 232 232和232Z 90 233 233 23三[                            91       186      173      187 *** ###\                            92       224      224      188 ### ]                            93       187      189      189 ***^                            94       176      95       106 *** ###_                            95       109      109      109`                            96       121      121      74  ###a 97129129 129号b 98 130 130 130电话c 99 131 131 131d 100 132 132 132电子101 133 133 133传真:102 134 134 134g 103 135 135 135克电话104 136 136 136i 105 137 137 137j 106 145 145 145k 107 146 146 146l 108147147 147号m 109 148 148 149米电话:110 149 149 149o 111 150 150 150第112页151 151 151q 113 152 152和152114 153 153一百五十三第115、162、162和162页电话:116 163 163u 117 164 164 167电话v 118 165 165 166版电话:119 166 166 116x 120 167 167 167y 121 168 168和168z 122 169 169 169{                            123      192      192      251 ###|                            124      79       79       79}                            125      208      208      253 ###~                            126      161      161      255 ###<删除>127 7 7 7<C1 0>128 32 32 32<C1 1>129 33 33 33<C1 2>130 34 34 34<C1 3>131 35 35 35<C1 4>132 36 36<C1 5>133 21 37 37***<C1 6>134 6 6 6<C1 7>135 23 23 23<C1 8>136 40 40 40 40<C1 9>137 41 41 41<C1 10>138 42 42 42<C1 11>139 43 43 43<C1 12>140 44 44 44<C1 13>141 9 9 9<C1 14>142 10 10 10<C1 15>143 27 27 27<C1 16>144 48 48 48<C1 17>145 49 49 49<C1 18>146 26 26 26<C1 19>147 51 51 51<C1 20>148 52 52 52<C1 21>149 53 53 53<C1 22>150 54 54 54<C1 23>151 8 8 8<C1 24>152 56 56 56<C1 25>153 57 57 57<C1 26>154 58 58 58<C1 27>155 59 59 59<C1 28>156 4 4 4<C1 29>157 20 20 20<C1 30>158 62 62 62<C1 31>159 255 255 95###<非断裂空间>160 65 65 65 65<倒排标记>161 170 170 170 170<中央符号>162 74 74 176###<吊牌>163 177 177 117<货币符号>164 159 159 159<日元标志>165 178 178<断条>166 106 106 208###<剖面图标志>167 181 181<迪亚雷斯>168 189 187 121***###<版权标志>169 180 180 180<女性ORDINATOR>170 154 154<指向左侧的GUILLEMET>171 138 138<未签名>172 95 176 186**###<软HYPHEN>173 202 202<注册商标标志>174 175 175<麦克龙>175 188 188 161###<学位标志>176 144 144<加号或最小标志>177 143 143<超级脚本二>178 234 234 233<超级脚本三>179 250 250 250<急性发作>180 190 190 190<微信号>181 160 160 160<段落标志>182 182<中点>183 179 179<塞迪拉>184 157 157<超级脚本一>185 218 218 219<MASC。ORDINAL指示符>186 155 155<右指式剪切仪>187 139 139 139<分数四分之一>188 183 183<分数一半>189 184 184<分数四分之三>190 185 185<反向问号>191 171 171<A带GRAVE>192 100 100 100<A急性>193 101 101 101<A带CIRCUMFLEX>194 98 98 98<A倾斜>195 102 102 102<A糖尿病>196 99 99 99<A,上面有环>197 103 103 103<大写字母AE>198 158 158 152<C与塞迪拉>199 104 104 104<带GRAVE>200 116 116 116<E急性>201 113 113 113<带CIRCUMFLEX的E>202 114 114<糖尿病>203 115 115 115<I带GRAVE>204 120 120 120<我患有急性>205 117 117<I WITH CIRCUMFLEX>206 118 118<糖尿病患者>207 119 119 119<大写字母ETH>208 172 172<N,倾斜>209 105 105 105<带GRAVE的O>210 237 237 238<O急性>211 238 238 239<O带CIRCUMFLEX>212 235 235<O,倾斜>213 239 239 238<O伴有腹泻>214 236 236 238<乘法符号>215 191 191 1911<O带冲程>216 128 128 128<U WITH GRAVE>217 253 253 224带GRAVE的U###<U急性>218 254 254 254<带CIRCUMFLEX的U>219 251 251 221###<U伴有腹泻>220 252 252 255<Y急性>221 173 186 173***###<大写字母THORN>222 174 174 174<小写字母尖S>223 89 89 89 89<带GRAVE>224 68 68 68<a急性>225 69 69 69<a带CIRCUMFLEX>226 66 66 66<a倾斜>227 70 70 70<糖尿病>228 67 67 67 67<a环上方>229 71 71 71 71<小配饰ae>230 156 156 156<c与塞迪拉>231 72 72 72<带GRAVE>232 84 84 84 84<e急性>233 81 81 81 81<使用CIRCUMFLEX>234 82 82 82 82<糖尿病>235 83 83 83<i带GRAVE>236 88 88 88<i急性>237 85 85 85<i带CIRCUMFLEX>238 86 86 86<i糖尿病>239 87 87 87<小写字母eth>240 140 140 140<n倾斜>241 73 73 73<o带GRAVE>242 205 205 205<o急性>243 206 206<o带CIRCUMFLEX>244 203 203 203<o倾斜>245 207 207 208<o糖尿病>246 204 204 204<分割标志>247 225 225 225<o有冲程>248 112 112 112<u带GRAVE>249 221 221 192###<u急性>250 222 222 2222<u带CIRCUMFLEX>251 219 219 218<u患有糖尿病>252 220 220 220<y急性>253 141 141<小号字母刺>254 142 142<y伴有腹泻>255 223 223 222

如果您更希望以CCSID 0037的顺序而不是ASCII+Latin-1的顺序查看上表,则通过以下方式运行该表:

配方2
perl-ne“if(/.{33}\d{1,3}\s{6,8}\d}1,3}\s{6,8}\d[1,3}\s}6,8{3}\s{6,8-}\d,1,3}/)”\-e“{push(@l,$_)}”\-e'结束{打印地图{$_->[0]}'\-e“排序{$a->[1]<=>$b->[1]}”-e'映射{[$_,substr($_,42,3)]}@l;}'佩勒比克.pod

如果您希望以CCSID 1047顺序查看,请将最后一行中的数字42更改为51,如下所示:

配方3
perl-ne“if(/.{33}\d{1,3}\s{6,8}\d}1,3}\s{6,8}\d[1,3}\s}6,8{3}\s{6,8-}\d,1,3}/)”\-e“{push(@l,$_)}”\-e'结束{打印地图{$_->[0]}'\-e“排序{$a->[1]<=>$b->[1]}”-e'映射{[$_,substr($_,51,3)]}@l;}'perlebcdic.pod文件

如果您希望以POSIX-BC顺序查看,请将最后一行中的数字51更改为60,如下所示:

配方4
perl-ne“if(/.{33}\d{1,3}\s{6,8}\d}1,3}\s{6,8}\d[1,3}\s}6,8{3}\s{6,8-}\d,1,3}/)”\-e“{push(@l,$_)}”\-e'结束{打印地图{$_->[0]}'\-e'排序{$a->[1]<=>$b->[1]}'\-e'映射{[$,substr($,60,3)]}@l;}'perlebcdic.pod文件

识别字符代码集

要从perl中确定正在运行的字符集,可以使用ord()或chr()的返回值来测试一个或多个字符值。例如:

$is_ascii=“A”eq chr(65);$is_ebcdic=“A”eq chr(193);

此外,“\t”是一个水平表格字符,以便:

$is_ascii=单词(“\t”)==9;$is_ebcdic=ord(“\t”)==5;

要区分EBCDIC代码页,请尝试查看其中一个或多个不同的字符。例如:

$is_ebcdic_37=“\n”eq chr(37);$is_ebcdic_1047=“\n”eq chr(21);

或者最好还是选择在任何代码集中唯一编码的字符,例如:

$is_ascii=ord('[')==91;$is_ebcdic_37=单词('[])==186;$is_ebcdic_1047=单词('[')==173;$is_ebcdic_POSIX_BC=ord('[')==187;

然而,编写以下测试是不明智的:

$is_ascii=“\r”ne chr(13);#错误$is_ascii=“\n”ne-chr(10);#不明智的

显然,第一种方法无法将大多数ASCII机器与CCSID 0037、1047或POSIX-BC EBCDIC机器区分开来,因为所有这些编码字符集下都有“\r”eq chr(13)。但也要注意,因为在MacIntosh(ASCII机器)上,“\n”是chr(13),“\r”是chr10$是_科学测试会给那里带来麻烦。

要确定perl是否是在EBCDIC代码页下构建的,可以这样使用Config模块:

使用配置;$is_ebcdic=$Config{'ebcdic'}eq'define';

转换

信托收据///

为了将字符串从一个字符集转换为另一个字符,只需要一个简单的数字列表,例如上表中的右列,以及perl的tr///操作符。表中的数据是ASCII顺序的,因此EBCDIC列提供了易于使用的ASCII到EBCDIC操作,这些操作也很容易颠倒。

例如,要将ASCII转换为代码页037,请从配方0的输出中获取第二列的输出(修改为添加\\字符),并在tr///中使用它,如下所示:

$cp_037='\000\001\002\003\234\011\206\177\227\215\216\013\014\015\016\017' .'\020\021\022\023\235\205\010\207\030\031\222\217\034\035\036\037' .'\200\201\202\203\204\012\027\033\210\211\212\213\214\005\006\007' .'\220\221\026\223\224\225\226\004\230\231\232\233\024\025\236\032' .'\040\240\342\344\340\341\343\345\347\361\242\056\074\050\053\174' .'\046\351\352\353\350\355\356\357\354\337\041\044\052\051\073\254' .'\055\057\302\304\300\301\303\305\307\321\246\054\045\137\076\077' .'\370\311\312\313\310\315\316\317\314\140\072\043\100\047\075\042' .'\330\141\142\143\144\145\146\147\150\151\253\273\360\375\376\261' .'\260\152\153\154\155\156\157\160\161\162\252\272\346\270\306\244' .'\265\176\163\164\165\166\167\170\171\172\241\277\320\335\336\256' .'\136\243\245\267\251\247\266\274\275\276\133\135\257\250\264\327' .'\173\101\102\103\104\105\106\107\110\111\255\364\366\362\363\365' .'\175\112\113\114\115\116\117\120\121\122\271\373\374\371\372\377' .'\134\367\123\124\125\126\127\130\131\132\262\324\326\322\323\325' .'\060\061\062\063\064\065\066\067\070\071\263\333\334\331\332\237' ;我的$ebcdic_string=$ascii_string;eval'$ebcdic_string=~tr/\000-\377/'$cp_037.“/”;

要从EBCDIC 037转换为ASCII,只需颠倒tr///参数的顺序,如下所示:

我的$ascii_string=$ebcdic_string;评估“$ascii_string=tr/”$cp_037。’/\000-\377/';

类似地,可以从配方0中获取第三列的输出,以获得$cp_1047表。配方0输出的第四列可以提供$cp_posix_bc表也适合转码。

图标(iconv)

XPG的可操作性通常意味着图标(iconv)实用程序,可从shell或C库中获得。有关iconv的信息,请参阅系统文档。

在OS/390上,请参阅iconv(1)手册页。从perl中调用iconv shell实用程序的一种方法是:

#OS/390示例$ascii_data=`echo'$ebcdic_data'|iconv-f IBM-1047-t ISO8859-1`

或逆映射:

#OS/390示例$ebcdic_data=`echo'$ascii_data'|iconv-f ISO8859-1-t IBM-1047`

有关其他基于perl的转换选项,请参阅CPAN上的Convert::*模块。

C RTL公司

OS/390 C运行时库提供_atoe()和_eto()函数。

操作员差异

这个..范围运算符在EBCDIC机器上小心处理某些字符范围。例如,以下数组在EBCDIC机器或ASCII机器上有26个元素:

@字母=('A'..'Z');#$#字母==25

在EBCDIC机器上运行的perl程序中,对字符串或字符数据进行操作时,位运算符(如&^|)可能会返回与在ASCII机器上运行时不同的结果。下面是一个改编自珍珠岩:

#基于EBCDIC的示例打印“j p \n”^“a h”;#打印“JAPH\n”打印“JA”|“ph\n”;#打印“japh\n”打印“JAPH\nJunk”&“\277\277\277\277\277”;#打印“japh\n”;打印“p N$”^“E<H \N”;#打印“Perl\n”;

ASCII表中32个C0控制字符的一个有趣特性是,它们可以“按字面”构造为perl中的控制字符,例如。(chr(0)eq“\c@”) (chr(1)eq“\cA”),等等。EBCDIC机器上的Perl已经被移植为将“\c@”转换为chr(0),将“\cA”转换为chr(1),但结果中的三十三个字符取决于您使用的代码页。下表使用上表中的字符名称,但有替换,如s/START OF/s.O./;s/结束/E.O./;s/传输/传输/;s/TABULATION/TAB./;s/垂直/垂直/;s/水平/水平/;s/设备控制/DC./;s/分离器/SEP./;s/否定确认/NEG。确认/;。POSIX-BC和1047集合在整个范围内是相同的,与0037集合只有一个点不同(21位小数)。请注意线路馈线字符可以由ASCII机器上的“\cJ”生成,但在1047或POSIX-BC机器上可以由“\cU”生成,并且不能作为“\c.字母。”0037机器上的控制字符。还要注意,“\c\\”映射到两个字符,而不是一个。

chr ord 8859-1 0037 1047和POSIX-BC------------------------------------------------------------------------“\c?”127<删除>“”***><“\c@”0<空><空>><空>**><“\cA”1<S.O.标题><S.O.HEADING><S.O标题>“\cB”2<S.O.文本>“\cC”3<E.O.文本>“\cD”4<E.O.传输><C1 28><C1 28>“\cE”5<询问><水平。表><水平。选项卡>“\cF”6<确认><C1 6>“\cG”7<贝尔><删除><删除>“\cH”8<退格><C1 23><C1 23>“\cI”9<水平。选项卡><C1 13><C1 13>“\cJ”10<线路馈电><C1 14>“\cK”11<垂直。表><垂直。表><垂直。选项卡>“\cL”12<表单馈送>“\cM”13<回车><回车><回车>“\cN”14<向外移位><向外移位>“\cO”15<向内换档>向内换档“\cP”16<数据链路退出>“\cQ”17<D.C.ONE><D.C.ONE><D.C.ONE>“\cR”18<D.C.TWO><D.C.2><D.C.TWO>“\cS”19<特区三>特区三>“\cT”20<D.C.FOUR><C1 29><C1 29>“\cU”21<阴性。确认><C1 5><线路馈电>***“\cV”22<同步空闲><退格>“\cW”23<E.O.传输块><C1 7><C1 7>“\cX”24<取消><取消>>“\cY”25<E.O.介质><E.O.介质><E.O.介质>“\cZ”26<替代><C1 18>“\c[”27<退出><C1 15>“\c\\”28<9月存档>\“\c]”29<集团SEP.><集团SEP.>>集团SEP.>“\c^”30<9月记录>>9月记录<“\c_”31<九月单元><九月单元>九月单元>**><

功能差异

chr()

必须为chr()提供一个EBCDIC代码参数,以便在EBCDIC机器上生成所需的字符返回值。例如:

$CAPITAL_LETTER_A=chr(193);
订单()

ord()将返回EBCDIC机器上的EBCDIC代码值。例如:

$the_number_193=单词(“A”);
包装()

pack()的c和c模板依赖于字符集编码。EBCDIC上的用法示例包括:

$foo=包(“CCCC”,193194195196);#$foo eq“ABCD”$foo=包(“C4”,193194195196);#同样的事情$foo=包(“ccxxcc”,193194195196);#$foo eq“AB\0\0CD”
打印()

对于传递给打印的包含ASCII编码的标量和字符串,必须小心。发生这种情况的一个常见位置是CGI脚本编写的MIME类型标头的输出。例如,许多perl编程指南都推荐类似的内容:

打印“Content-type:\text/html\015\012\015\012”;#在EBCDIC上这可能是错误的

例如,在IBM OS/390 USS Web Server下,您应该将其写为:

print“Content-type:\ttext/html\r\n\r\n”;#适用于DGW等

这是因为在这种情况下,从EBCDIC到ASCII的转换是由web服务器完成的(然而,这种代码不适用于Macintosh)。有关详细信息,请参阅web服务器的文档。

打印()

在EBCDIC机器上执行时,可以将字符转换为数字,反之亦然的格式与ASCII格式不同。示例包括:

printf(“%c%c%c”,193194195);#打印ABC
排序()

EBCDIC排序结果可能与ASCII排序结果不同,特别是对于混合大小写字符串。下面将对此进行更详细的讨论。

冲刺()

请参阅上面对printf()的讨论。使用sprintf的一个例子是:

$CAPITAL_LETTER_A=冲刺(“%c”,193);
解压缩()

请参阅上面关于pack()的讨论。

常规表达差异

从perl 5.005_03开始,字母范围正则表达式(如[A-Z]和[A-Z])已经过专门编码,以避免拾取空格字符。例如,字符,如o使用CIRCUMFLEX位于I和J之间的值将无法与正则表达式范围匹配/【H-K】/.

如果您确实想匹配单个八位正则表达式中的字母间隙字符,请尝试匹配十六进制或八进制代码,例如/\313/EBCDIC或/\364/在ASCII机器上进行正则表达式匹配o带圆形.

另一个需要注意的构造是在正则表达式中不适当地使用十六进制或八进制常量。考虑以下一组短节:

子is_c0{my$char=子项(移位,0,1);$char=~/[\000-\037]/;}子is_print_ascii{my$char=substr(移位,0,1);$char=~/[\040-\176]/;}子is_delete{my$char=子项(移位,0,1);$char eq“\177”;}子is_c1{my$char=子项(移位,0,1);$char=~/[\200-\237]/;}子is_latin_1{my$char=子项(移位,0,1);$char=~/[\240-\377]/;}

如果只关注数字代码点,那么上述内容就足够了。然而,问题可能是字符而不是代码点,在EBCDIC机器上,可能需要以下构造if(is_print_ascii(“A”)){print“A是可打印字符\n”;}以打印出预期的消息。表示上述字符分类子集合的一种方法是:

子Is_c0{my$char=子项(移位,0,1);if(ord('^')==94){#ascii返回$char=~/[\000-\037]/;} if(ord('^')==176){#37返回$char=~/[\000-\003\067\055-\057\026\005\045\013-\023\074\075\062\046\030\031\077\034-\037]/;}if(ord('^')==95||ord('^')==106){#1047||posix-bc返回$char=~/[\000-\003\067\055-\057\026\005\025\013-\023\074\075\062\046\030\031\077\034-\037]/;}}子Is_print_ascii{my$char=子项(移位,0,1);$char=~/[!“\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\]^_`A-Z{|}~]/;}子Is_delete{my$char=子项(移位,0,1);if(ord('^')==94){#ascii返回$char eq“\177”;}其他{#ebcdic返回$char eq“\007”;}}子Is_c1{my$char=子项(移位,0,1);if(ord('^')==94){#ascii返回$char=~/[\200-\237]/;}if(ord('^')==176){#37return$char=~/[\040-\044\025\006\027\050-\054\011\012\033\060\061\032\063-\066\010\070-\073\040\024\076/377]/;}if(ord('^')==95){#1047返回$char=~/[\040-\045\006\027\050-\054\011\012\033\060\032\063-\066\010\070-\073\004\024\076\377]/;}if(ord('^')==106){#posix-bc返回$char=~/[\040-\045\006\027\050-\054\011\012\033\060\061\032\063-\066\010\070-\073\040\024\076\137]/;}}子Is_latin_1{my$char=子项(移位,0,1);if(ord('^')==94){#ascii返回$char=~/[\240-\377]/;}if(ord('^')==176){#37返回$char=~/[\101\252\112\261\237\262\152\265\275\264\232\212\137\312\257\274\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\375\376\373\374\255\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\335\336\333\334\215\216\337]/;}如果(ord('^')==95){#1047返回$char=~/[\101\252\112\261\237\262\152\265\273\264\232\212\260\312\257\274\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\375\376\373\374\272\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\335\336\333\334\215\216\337]/; }if(ord('^')==106){#posix-bc返回$char=~/[\101\252\260\261\237\262\320\265\171\264\232\212\272\312\257\241\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\340\376\335\374\255\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\300\336\333\334\215\216\337]/;}}

但请注意,只有Is_asci_print()sub实际上与编码字符集无关。另一种写作方式Is_latin_1()将显式使用范围中的字符:

子Is_latin_1{my$char=子项(移位,0,1);$char=~/[…………..¡°¡°¡±¡°¡¤¡°¡¨¡¤¨¡¨£¨¡°;}

尽管该表单可能在网络传输中(由于存在8位字符)或在非ISO拉丁字符集上遇到问题。

插座

大多数套接字编程都假定ASCII字符按网络字节顺序编码。例外情况包括在主机web服务器下编写CGI脚本,服务器可能会为您处理翻译。大多数主机web服务器在输出上将EBCDIC数据转换为ISO-8859-1或Unicode。

分拣

基于ASCII的字符集和EBCDIC字符集之间的一个巨大区别是大小写字母的相对位置以及字母与数字的比较。如果在基于ASCII的机器上排序,医生的两个字母缩写位于驱动器的两个字母之前,即:

@sorted=排序(qw(Dr.Dr.));#@ASCII的排序保留('Dr.','Dr.'),#但是('dr.','dr.')在EBCDIC上

EBCDIC中大写字母之前小写字母的属性甚至被带到拉丁语1 EBCDIC页面,如0037和1047。例如,ËE有腹泻(203)位于e有腹泻(235)在ASCII机器上,但后者(83)在EBCDIC机器上位于前者(115)之前。(敏锐的读者会注意到大写版本的ß小字母尖S简单地说就是“SS”,大写形式的y与腹泻不在0..255范围内,但在Unicode中为U+x0178,或“\x{178}”在支持Unicode的Perl中)。

排序顺序将导致ASCII机器与EBCDIC机器上获得的结果之间的差异。以下是关于如何处理这些差异的一些建议。

忽略ASCII与EBCDIC排序差异。

这是计算成本最低的策略。它可能需要一些用户教育。

然后对数据进行排序。

为了尽量减少单套管混合测试的费用,尝试信托收据///针对数据中最常用的字符集情况。如果数据主要为大写非拉丁1,则应用tr/[a-z]/[a-z]/,然后应用sort()。如果数据主要是小写非拉丁文1,则在排序之前应用tr/[A-Z]/[A-Z]/。如果数据主要为大写,并且包含拉丁语-1字符,则适用:

tr/[a-z]/[a-z]/;tr/[ááässaterie eiether eiþðñonounoutöounhousuüৰ]/[我的圣洁之家]/;s/ß/SS/g;

然后sort()。但请注意,这种拉丁语-1的操作并没有解决y与腹泻在ASCII机器上保留在编码点255处的字符,但在大多数EBCDIC机器上保留223处的字符。使用支持Unicode的Perl,您可以尝试:

tr/^/\x{178}/;

排序前的单套管数据策略无法保留数据的情况,因此可能无法接受。

转换、排序数据,然后重新转换。

这是不使用网络连接的最昂贵的方案。

仅在一种类型的机器上执行分拣。

此策略可以使用网络连接。因此,计算成本很高。

传输格式

有多种方法可以使用字符集内映射来转换数据,以满足各种用途。上一节讨论了排序,接下来讨论了其他一些更流行的映射技术。

URL解码和编码

请注意,一些URL中有十六进制ASCII代码点,以试图克服字符或协议限制问题。例如,并不是每个键盘上都有波浪号字符,因此会出现以下形式的URL:

网址:http://www.pvhp.com/~百万千瓦时/

也可以表示为:

http://www.pvhp.com/%7Epvhp/http://www.pvhp.com/%7epvhp/

其中7E是“~”的十六进制ASCII码位。以下是在CCSID 1047下解码此类URL的示例:

$url='http://www.pvhp.com/%7Epvhp/';#此数组假定代码页1047我的@a2e_1047=(0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 21, 11, 12, 13, 14, 15,16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109,121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7,32, 33, 34, 35, 36, 37,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27,48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255,65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188,144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171,100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119,172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89,68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87,140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223);$url=~s/%([0-9a-fA-F]{2})/pack(“c”,$a2e_1047[十六进制($1)])/ge;

相反,以下是在1047代码页下对此类URL进行编码的部分解决方案:

$url='网址:http://www.pvhp.com/~pvhp/';#此数组假定代码页1047我的@e2a_1047=(0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15,16, 17, 18, 19,157, 10,  8,135, 24, 25,146,143, 28, 29, 30, 31,128,129,130,131,132,133, 23, 27,136,137,138,139,140,  5,  6,  7,144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26,32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124,38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94,45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63,248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34,216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177,176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164,181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174,172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215,123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245,125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255,92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213,48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159);#以下正则表达式不处理#映射:('.'=>'%2E','/'=>'%2F',':'=>'%3A')$url=~s/([\t“#%&\(\),;<=>\?\@\[\\]^`{|}~])/短跑(“%%%02X”,$e2a_1047[ord($1)])/ge;

其中一个更完整的解决方案是将URL拆分为多个组件,并仅对相应的部分应用完整的s///替换。

在其余示例中,可以使用@e2a或@a2e数组,但不会显式显示赋值。对于代码页1047,您可以使用刚刚显示的@a2e_1047或@e2a_1047数组。

uu编码和解码

这个u个将EBCDIC数据转换为EBCDIC字符,使其等效于ASCII字符。例如,以下内容将在ASCII或EBCDIC计算机上打印“确实是”:

$all_byte_chrs=“”;对于(0..255){$all_byte_chrs.=chr($_);}$uuencode_byte_chrs=包('u',$all_byte.chrs);($uu=<<‘ENDOFEREDOC’)=~s/^\s*//gm;M``$“`P0%!@<(”0H+#`T.#Q`1$A,4%187&!D:&QP='A\@(2(C)“4F)R@I*BLLM+2XO,#$R,S0U-C<X.3H[/#T^/T!!0D-$149'2$E*2TQ-3D]045)35%565UA9M6EM<75岁?8&%B8V1E9F=H:6IK&联合国;W!Q<G-T=79W>'EZ>WQ]?G^`@8*#A(6&MAXB)BHN,C8Z/D)和2DY25EI>8F9J;G) V>GZ“AHJ.DI::GJ*FJJZRMKJ^PL;*SMM+6VM[BYNKN\O;Z_P,'“P\3%QL?(R<K+S,W.S]#1TM/4U=;7V-G:V]S=WM_@?十> +CY.7FY^CIZNOL[>[O\/'R\_3U]O?X ^?K[_/W^_P``内非赫雷多克if($uuencode_byte_chrs等于$uu){打印“是”;}$uudecode_byte_chrs=解压缩('u',$uuencode_byte _chrs);if($uudecode_byte_chrs等于$all_byte-chrs){打印“确实\n”;}

下面是一个非常简单的uudecoder,它将在EBCDIC上工作,前提是正确填写了@e2a数组:

#!/usr/local/bin/perl@e2a=(#必须填写此项);$_=<>直到($mode,$file)=/^begin\s*(\d*)\s*(\s*)/;如果$file ne“”,则打开(OUT,“>$file”);同时(<>){last if/^end/;下一个if/[a-z]/;下一个除非int(((($e2a[ord()]-32)&077)+2)/3)==int(长度()/4);打印OUT unpack(“u”,$_);}关闭(OUT);chmod oct($mode),$file;

引用的可打印编码和解码

在ASCII编码机器上,可以使用以下方法去除可打印集之外的字符:

#此QP编码器仅适用于ASCII$qp_string=~s/([=\x00-\x1F\x80-\xFF])/sprintf(“=%02X”,ord($1))/ge;

然而,在ASCII和EBCDIC机器上工作的QP编码器看起来有点像下面这样(为了简洁起见,省略了EBCDIC分支@e2a数组):

if(ord('A')==65){#ASCII$删除=“\x7F”;#ASCII码@e2a=(0..255)#ASCII到ASCII标识映射}其他{#EBCDIC$删除=“\x07”;#EBCDIC公司@e2a=#EBCDIC到ASCII映射(如上所示)}$qp_string=~s/([^!“\#\$%&'()*+,\-.\/0-9:;<>?\@A-Z[\\]^_`A-Z{|}~$delete])/sprintf(“=%02X”,$e2a[ord($1)])/ge;

(尽管在生产代码中,替换可以在带有@e2a数组的EBCDIC分支中完成,也可以在ASCII分支中单独完成,而不需要消耗标识映射)。

此类QP字符串可以通过以下方式解码:

#此QP解码器仅限于ASCII$string=~s/=([0-9A-Fa-f][0-9A-Fa-f])/chr十六进制$1/ge;$string=~s/=[\n\r]+$//;

然而,在ASCII和EBCDIC机器上工作的QP解码器看起来有点像下面这样(为了简洁起见,省略了@a2e数组):

$string=~s/=([0-9A-Fa-f][0-9A-Fa-f])/chr$a2e[十六进制$1]/ge;$string=~s/=[\n\r]+$//;

凯撒柏树

将字母表中的一个或多个字符移位进行加密的做法可以追溯到数千年前,盖乌斯·朱利叶斯·凯撒(Gaius Julius Caesar)在其高卢之战文本。单个字母移位有时被称为旋转,移位量在字符串“rot”或“rot$n”之后以数字$n表示。Rot0和rot26将在拉丁字母表的26个字母的英文版本上指定身份图。Rot13有一个有趣的特性,即后续的替代调用是身份映射(因此,在26个字母循环组中,Rot13是它自己的非平凡逆)。因此,以下是将在ASCII和EBCDIC机器上工作的rot13编码器和解码器:

#!/usr/local/bin/perl同时(<>){tr/n-za-mN-za-M/a-za-Z/;打印;}

单线形式:

perl-ne’tr/n-za-mN-za-M/a-za-Z/;打印'

散列顺序和校验和

XXX(XXX)

I18N和L10N

即使在EBCDIC机器上,至少原则上也支持国际化(I18N)和本地化(L10N)。细节取决于系统,并在perlebcdic中的“操作系统问题”第节。

多八位字节字符集

多字节EBCDIC代码页;Unicode、UTF-8、UTF-EBCDIC、XXX。

操作系统问题

EBCDIC Perl程序员可能会关注一些与系统相关的问题。

操作系统/400

PASE环境。

IFS访问

XXX。

操作系统/390

Perl在Unix Systems Services或USS下运行。

chcp公司

chcp公司支持作为shell实用程序显示和更改代码页。另请参见chcp公司.

数据集访问

对于顺序数据集访问,请尝试:

my@ds_records=`cat//DSNAME`;

或:

my@ds_records=`cat//'HLQ。DSNAME“;

另请参阅CPAN上的OS390::Stdio模块。

OS/390图标

图标(iconv)支持作为shell实用程序和C RTL例程。另请参阅iconv(1)和iconw(3)手册页。

区域设置

在OS/390上,请参阅区域设置有关区域设置的信息。L10N文件位于/usr/nls/locale.$Config{d_setlocale}在OS/390上为“define”。

VM/ESA?

XXX。

POSIX-BC?

XXX。

漏洞

此pod文档包含字面拉丁1字符,可能会遇到翻译困难。特别是,已知一个流行的nroff实现在试图通过吊舱2man程序(例如,您可能会看到一个而不是像在中那样带着日记的。另一个nroff在第一次出现8位字符时截断了生成的手册页。

并非所有外壳都允许多个-e(电子)将perl的字符串参数正确地连接在一起,就像配方2、3和4所暗示的那样。

Perl还不能在EBCDIC平台上使用任何Unicode功能。

另请参阅

珍珠岩,珀尔func.

参考文献

http://anubis.dkuug.dk/i18n/charmaps

网址:http://www.unicode.org/

http://www.unicode.org/unicode/reports/tr16/

http://www.wps.com/texts/codes/ASCII:美国信息渗透标准代码汤姆·詹宁斯,1999年9月。

Unicode标准2.0版Unicode联盟,ISBN 0-201-48345-9,Addison-Wesley Developers Press,1996年7月。

Unicode标准3.0版Unicode Consortium,Lisa Moore编辑,ISBN 0-201-61633-5,Addison Wesley Developers Press,2000年2月。

CDRA:IBM-字符数据表示体系结构-参考和注册表,IBM SC09-2190-001996年12月。

“解密字符集”,Andrea Vine,多语言计算与技术,#26第10卷第4期1999年8月/9月;ISSN 1523-0309;多语言计算公司Sandpoint ID,美国。

代码、密码和其他秘密通信Fred B.Wrixon,ISBN 1-57912-040-7,Black Dog&Leventhal Publishers,1998年。

作者

彼得·普里默pvhp@best.com1999年和2000年,在Chris Leach和AndréPirard的帮助下,CCSID 0819和0037编写了这篇文章A.Pirard@ulg.ac.be以及托马斯·多纳(Thomas Dorner)提供的POSIX-BC帮助Thomas.Dorner@start.de。还要感谢Vickie Cooper、Philip Newton、William Raffloer和Joe Smith。本文件中使用的商标、注册商标、服务商标和注册服务商标是其各自所有者的财产。

1 POD错误

分析POD时遇到以下错误:

834号线附近:

之前看到的非ASCII字符=编码在'/[…………..¡°¡°¡±¡±¡°¡¤¡¤§¡¤编号]/;'。假设CP1252