在Swift中使用ASCII值更改字符的值

4

我正在尝试通过改变每个单独字符来更改字符串。

目前,我的做法是逐个字符读取字符串,尝试将其转换为ASCII,并将值加一。以下是我的代码。

  var phrase = textfield1.text
    var i = 0
    for character in phrase
    {
        var s = String(character).unicodeScalars
        s[s.startIndex].value
        println(s[s.startIndex].value)
       if(i == 0)
        {
            s[s.startIndex].value += 1
        }
        if(i == 1)
        {
            s = s + 2
            i = 0
        }
    }

我的println输出了我输入的任何单词的正确值,但是当我尝试在if语句中操作它时,就会出现以下错误:

Could not find member 'value'

我想知道我所尝试的是否可能实现?

3个回答

8
< p > unicodeScalars 属性是只读的,所以您不能直接修改它。

您可以通过从(修改后的)Unicode标量构建新字符串来实现:

var text = "HELLO  !"
var newText = ""

for uni in text.unicodeScalars {
    var val = uni.value
    if val >= 0x41 && val < 0x5A { // If in the range "A"..."Y", just as an example
        val += 1 // or whatever ...
    }
    newText.append(UnicodeScalar(val))
}

println(newText) // "IFMMP  !"

但是请注意,val 是一个 Unicode 值,而不是 ASCII 码。在修改它之前,您可能需要添加一个检查,确保 val 在字母数字字符或类似字符的范围内。


Swift 3 更新:(感谢 @adrian)

let text = "HELLO  !"
var newText = ""

for uni in text.unicodeScalars {
    var val = uni.value
    if val >= 0x41 && val < 0x5A { // If in the range "A"..."Y", just as an example
        val += 1 // or whatever ...
    }
    newText.append(Character(UnicodeScalar(val)!))
}

print(newText) // "IFMMP  !"

它看起来像是指定新字符的UnicodeScalar值的方法已经改变了。我找到了这个链接,但我不知道我应该怎么做。https://github.com/apple/swift/blob/master/stdlib/public/core/String.swift - Adrian
@Adrian:我回到电脑前会更新它。 - Martin R
太棒了!我在取得一些进展……如果我比你先完成,我会发表评论的。我正在尝试使用 var stringMap = string.unicodeScalars.map({$0.value}) 将它们全部映射出来,并通过 switch 运行元素进行递增。 - Adrian
让我成功的是 let newChar = UnicodeScalar(value); newString.append(Character(newChar!)) - Adrian

7
您之所以会遇到这个错误,是因为UnicodeScalarvalue属性是只读的,而您正在尝试对其进行递增操作。
请注意,在循环中更改内容不会影响phrase - 这里有一种使用map()来实现您正在做的事情的方法:
let advanced = String(map(phrase) {
    (ch: Character) -> Character in
    switch ch {
    case " "..."}":                                  // only work with printable low-ASCII
        let scalars = String(ch).unicodeScalars      // unicode scalar(s) of the character
        let val = scalars[scalars.startIndex].value  // value of the unicode scalar
        return Character(UnicodeScalar(val + 1))     // return an incremented character
    default:
        return ch     // non-printable or non-ASCII
    }
})

这可能在此处不是问题,但是这将截断诸如旗帜""之类的“扩展字形群集”。 - Martin R
1
你可以通过添加检查 if ch < "A" || ch > "Y" { return ch } 或适合任务的其他操作来修复它。 (对所有Unicode字符进行递增可能没有意义。) - Martin R

0

我最终想出了一个非常简单的解决方案。

一旦我将数字转换完成,我只需将其存储在一个新变量中即可。

s = String(character).unicodeScalars
x = s[s.startIndex].value

x += 1

但这并不修改字符串。我们是否误解了你的问题? - Martin R
它不直接修改字符串,但它允许我更改单个字符。有可能我没有清楚地解释问题。 - AndyReifman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接