我正在尝试将一个非常长的字符串转换为ASCII十六进制。
我该怎么做呢?
我已经写了这个非常长的switch语句,但我知道有一种更简单的方法来实现这一点。我对所有奇怪的符号都有问题,比如括号,#,$,\等等。在switch语句中。我可以让他们中的一些人使用反斜杠工作,但其他人失败了。
proc Text_to_ASCII {string} {
set Ascii_Word ""
set stringLength [string length $string]
for {set i 0} {$i < $stringLength} {incr i} {
set Letter [string index $string $i]
switch -glob $Letter {
" " {set hex_ascii 20}
0 {set hex_ascii 30}
1 {set hex_ascii 31}
2 {set hex_ascii 32}
3 {set hex_ascii 33}
4 {set hex_ascii 34}
5 {set hex_ascii 35}
6 {set hex_ascii 36}
7 {set hex_ascii 37}
8 {set hex_ascii 38}
9 {set hex_ascii 39}
A {set hex_ascii 41}
B {set hex_ascii 42}
C {set hex_ascii 43}
D {set hex_ascii 44}
E {set hex_ascii 45}
F {set hex_ascii 46}
G {set hex_ascii 47}
H {set hex_ascii 48}
I {set hex_ascii 49}
J {set hex_ascii 4A}
K {set hex_ascii 4B}
L {set hex_ascii 4C}
M {set hex_ascii 4D}
N {set hex_ascii 4E}
O {set hex_ascii 4F}
P {set hex_ascii 50}
Q {set hex_ascii 51}
R {set hex_ascii 52}
S {set hex_ascii 53}
T {set hex_ascii 54}
U {set hex_ascii 55}
V {set hex_ascii 56}
W {set hex_ascii 57}
X {set hex_ascii 58}
Y {set hex_ascii 59}
Z {set hex_ascii 5A}
a {set hex_ascii 61}
b {set hex_ascii 62}
c {set hex_ascii 63}
d {set hex_ascii 64}
e {set hex_ascii 65}
g {set hex_ascii 67}
h {set hex_ascii 68}
i {set hex_ascii 69}
j {set hex_ascii 6A}
k {set hex_ascii 6B}
l {set hex_ascii 6C}
m {set hex_ascii 6D}
n {set hex_ascii 6E}
o {set hex_ascii 6F}
p {set hex_ascii 70}
q {set hex_ascii 71}
r {set hex_ascii 72}
s {set hex_ascii 73}
t {set hex_ascii 74}
u {set hex_ascii 75}
v {set hex_ascii 76}
w {set hex_ascii 77}
x {set hex_ascii 78}
y {set hex_ascii 79}
z {set hex_ascii 7A}
default {set hex_ascii 3F}
}
append Ascii_Word $hex_ascii
}
return $Ascii_Word
}所以我一直在尝试这段代码...
proc string2hex {s} {
binary scan $s H* hex
regsub -all (..) $hex {\\x\1}
}
set input_string "lol"
set ascii_string [string2hex $input_string]返回"\x6c\x6f\x6c“,非常接近我想要的"6c6f6c”如何删除\x?我正在考虑只做两次trimleft来去掉每个字符的\x,也许只需要一次输入一个字符……
想法?
发布于 2018-02-01 19:48:06
这取决于你到底指的是什么。你的意思是真的“将这个字符串转换成ASCII码,并用?替换未知字符”(或其他字符),还是“获取这个字符串中所有字符的Unicode字符代码”?第二个可能是最有可能的:
proc string_to_ascii {string_value} {
return [lmap c [split $string_value ""] {
scan $c %c code
# Make the code the result of this inner script
string cat $code
}]
}这不是最有效的版本。对于长字符串,事实证明,做这个更长的版本是一个巨大的胜利:
proc string_to_ascii {string_value} {
set map {}
set result [lrepeat [string length $string_value] DUMMY]
set idx 0
foreach c [split $string_value ""] {
if {![dict exists $map $c]} {
scan $c %c ch
dict set map $c $ch
}
lset result $idx [dict get $map $c]
incr idx
}
return $result
}这是一个胜利,原因有两个:
split命令在拆分字符时使用的策略相同( binary scan也是如此),即使字符串非常短,也能获得巨大的性能优势。但这一切都要复杂得多。使用第一个版本(或者使用简单的split $str {},如果你不需要立即使用代码点),因为它更容易编写,并且在内部进行了很好的优化。
要强制字符串仅为ASCII,您可以这样做:
encoding convertto ascii $input_string从技术上讲,结果是一个字节数组,但作为ASCII字符串工作得很好。如果你想检测非ASCII码(例如,你可以抱怨它),那么你可以使用string is ascii
if {![string is ascii -failindex idx $input_string]} {
error "found non-ASCII char at index $idx \"[string index $input_string $idx]\""
}如果您不关心坏字符在哪里,那么一个简单的string is ascii $input_string就可以了。
发布于 2018-03-14 05:12:47
这是我的最终代码..。
proc Text_to_ASCII {string} {
binary scan $string H* hex
set Ascii_Word [regsub -all (..) $hex {\1}]
set stackoverflow_users "People who don't have programming jobs because they
can't write code with crap are the people who have spare time to answer
programming question on stackoverflow"
}发布于 2018-02-01 15:08:28
我相信你正在寻找的东西是
binary format a* [encoding convertto ascii $string_value]结果对我来说肯定像ASCII,尽管我不能确定这就是你想要的。
更新:我仍然对期望的目标以及为什么现有的答案都没有用感到有点困惑。如果预期输入中的字符都不在ASCII范围之外,则UTF-8字符串与ASCII字符串相同:没有要转换的字符。
如果有非ASCII字符:转换很有用:
% encoding convertto ascii abcåäö
abc???结果是一个UTF-8 / ASCII字符串。
如果需要简单地获取字符串中每个字符的低位字节,并将每个字符掩码为7位:
% join [lmap c [split [binary format a* abcåäö] {}] {format %c [expr {[scan $c %c] & 0x7f}]}] {}
abcedv如果您想从字符串中获取十六进制代码:
% binary encode hex abcåäö
616263e5e4f6在这种情况下,不进行转换(当然,如果输入已经是ASCII,则可以进行转换):与其他方法组合以获得纯ASCII,例如:
% binary encode hex [encoding convertto ascii abcåäö]
6162633f3f3f文档:binary、encoding
https://stackoverflow.com/questions/48551814
复制相似问题