在Swift中在不可打印的字符上分割字符串 [英] Splitting a string on a non-printable character in Swift

查看:105
本文介绍了在Swift中在不可打印的字符上分割字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Swift中将从条形码读取的字符串拆分成一个数组,在讨论代码点,unicode标量和字素簇时,我有些迷茫了.

I'm attempting to split a string I've read from a barcode into an array in Swift and I'm getting somewhat lost in the discussion of codepoints, unicode scalars and grapheme clusters...

条形码字符串包含"FNC1"定界符,我相信它的ASCII值为232或29(我发现有冲突的文档),因此该字符串具有以下形式:

The barcode string contains "FNC1" delimiters which I believe has either an ASCII value of 232 or of 29 (I've found conflicting documentation), so the string is of this form:

FNC1019931265099999891T77FNC1203000FNC19247

我希望正确的数组拆分输出为: ["019931265099999891T77", "1203000", "19247"]

I'd expect the correct array split output to be: ["019931265099999891T77", "1203000", "19247"]

我已经尝试过这样的方法:

I've tried an approach like this:

var codeArray = barcodeString.componentsSeparatedByString("\u{232}")var codeArray = barcodeString.componentsSeparatedByString("\u{29}")

但是找不到"\u{232}""\u{29}",因此我的语法错误或FNC1的ascii值不正确.

But neither "\u{232}" or "\u{29}" are being found so either my syntax is wrong or the ascii value of FNC1 is incorrect.

如果我遍历条形码字符串,则每个字符的utf8值都会打印出来,FNC1字符显示为整数29,但是我认为这是一个代码点,而不是整数-我当然不能与整数进行比较检测到它,这会导致编译器错误.

If I loop through the barcodeString printing the utf8 values for each character the FNC1 character displays as if it were the integer 29, however I believe this is a codepoint not an integer - I certainly can't do an integer based comparison to detect it, that gives a compiler error.

找出此字符如何在Swift字符串中表示并与之进行比较/分割的正确方法是什么?

What would be the correct way to work out how this character is represented in a Swift string and to compare/split against it?

更新 问题归结为如何从单个字符中查找ascii代码值,以及如何从另一字符中查找ascii代码值,如果您具有整数ascii代码值,则生成一个字符.

Update The problem boils down to how to find the ascii code value from a single character and how to go the other way, generating a character if you have an integer ascii code value.

我已经为此发布了骇人听闻的解决方案,但是必须有一种更整洁,更可靠的方法.

I've posted my hacky solution to this as an answer but there must be a neater, more robust way to do it.

推荐答案

所以我想出的最好的办法是遍历字符串,查看每个字符,将每个单独的字符转换为字符串,这样我就可以得到一个价值.

So the best I've come up with is to loop through the string looking at each character, converting each individual character to a string so I can then get a value for it.

由于我找不到直接直接获取字符的ascii值的方法,因此必须将每个字符依次转换为字符串,然后unicodeScalars属性允许我访问代表字符串元素的值,这些值是UInt32因此,可以通过一些类型转换将它们与不可打印字符的整数值进行比较.

As I can't find a way to get the ascii value of a character directly each character in turn has to be cast to a string then the unicodeScalars property lets me access the values that represent the string elements, these values are UInt32 so they can be compared to the integer value of the non-printable character with a bit of typecasting.

混乱,但这是我迄今为止找到的唯一答案.

Messy but so far the only answer I've found.

    func barcodeStringToArray(inputString: String, asciiValue: Int, splitString: String) -> Array<String>? {
        var results = [""]
        var replacedString = ""

        for myChar in inputString {
            let tmpString: String = String(myChar)
            for myChar in tmpString.unicodeScalars {
                if myChar.value == UInt32(asciiValue) {
                    replacedString += splitString
                } else {
                    replacedString += "\(myChar)"
                }
                //Can there ever be more than one element in this array?
                //Does an extended grapheme clusters come up as multiple elements?
                break
            }
        }
        results = replacedString.componentsSeparatedByString(splitString)
        //Now remove any empty arrays
        results = results.filter({$0 != ""})
        return results
    }

这篇关于在Swift中在不可打印的字符上分割字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆