在Swift中如何在字符串的特定索引处添加一个字符

67
我在Swift中有一个像这样的字符串:
var stringts:String = "3022513240"

如果我想将它更改为类似于这样的字符串:"(302)-251-3240",我想在索引0处添加括号,我该如何做呢?
在Objective-C中,可以这样做:
 NSMutableString *stringts = "3022513240";
 [stringts insertString:@"(" atIndex:0];

如何在Swift中实现?

你尝试过这个吗?stringts.insert("(", atIndex: 0) - Dharmesh Kheni
它给了我一个错误:类型:'String.index'不符合协议'IntegerLiteralConvertible'。 - lakshmen
11个回答

97

Swift 3

使用原生的 Swift 方法:

var welcome = "hello"

welcome.insert("!", at: welcome.endIndex) // prints hello!
welcome.insert("!", at: welcome.startIndex) // prints !hello
welcome.insert("!", at: welcome.index(before: welcome.endIndex)) // prints hell!o
welcome.insert("!", at: welcome.index(after: welcome.startIndex)) // prints h!ello
welcome.insert("!", at: welcome.index(welcome.startIndex, offsetBy: 3)) // prints hel!lo

如果你对字符串和性能方面有兴趣,可以看一下@Thomas Deniau在下面的回答


52
如果你将它声明为 NSMutableString,那么可以这样做:
let str: NSMutableString = "3022513240)"
str.insert("(", at: 0)
print(str)

输出为:

(3022513240)

编辑:

如果您想在开头添加:

var str = "3022513240)"
str.insert("(", at: str.startIndex)

如果您想在最后一个索引处添加字符:

str.insert("(", at: str.endIndex)

如果您想在特定的索引位置添加内容:

str.insert("(", at: str.index(str.startIndex, offsetBy: 2))

7
不要那样做,因为如果你的字符串包含了你没有预料到的Unicode字符,你可能会插入到字形簇的中间。相反,看看你如何获取索引,并使它们适合String.Index,以设计一个对Unicode友好的流程。 - Thomas Deniau
1
编辑 Swift 3 的答案 - fnc12
问题是关于Swift的,它有自己的“String”。例如,你会用C代码回答每个Objective-C问题吗?被踩了。 - Vyachaslav Gerchicov
如何从NSMutableString中删除第一个元素 - Menaim

12
var myString = "hell"
let index = 4
let character = "o" as Character

myString.insert(
    character, at:
    myString.index(myString.startIndex, offsetBy: index)
)

print(myString) // "hello"

注意:确保index小于或等于字符串的大小,否则会导致崩溃。


为什么这是一个被接受的答案?"advance"是什么意思?这不是可运行的代码。 - breakline
@breakline已修复。 - Eric
1
小于或等于,对吧?如果更大,就会崩溃。 - Guilherme

10
也许这个适用于Swift 4的扩展能帮到你:
extension String {
  func insert(_ string: String, at index: Int) {
    self.insert(contentsOf: string, at: self.index(self.startIndex, offsetBy: index))
  }
}

1
请解释一下你的代码,以便其他用户能够理解其功能。谢谢! - Ignacio Ara
他(@IgnacioAra)所说的没错!另外,你提供的代码是错误的。请看下面我的回答。 - Dilapidus
@IgnacioAra 我刚刚将本地插入函数的String.Index参数替换为Integer,以便更容易使用。 - Murat Uygar
@Dilapidus 我已经测试过我的代码,没有任何问题。它按照我所希望的工作。怎么了?我看了你的答案,你的和我的没有任何区别。 - Murat Uygar
1
嗨,@DilmuratAbduqayyum,你正在针对传递的字符串进行索引,而不是self。对我来说,你的代码立即出现错误,因为“ind”几乎总是大于传递的字符串的长度。请注意,我已将“string.index”和“string.startIndex”中的字符串替换为self。 - Dilapidus
@DilmuratAbduqayyum 我直接将你的代码粘贴到我的代码中,出现了问题。如果你修改了你的代码,我很乐意删除我的答案。不过我很感激你的回答,因为它让我找到了一个非常好的解决方案来解决我的问题。 - Dilapidus

6

var phone= "+9945555555"

var indx = phone.index(phone.startIndex,offsetBy: 4)

phone.insert("-", at: indx)

index = phone.index(phone.startIndex, offsetBy: 7)

phone.insert("-", at: indx)

//+994-55-55555

以上代码是将电话号码格式化的示例。在这个示例中,我们使用了Swift编程语言来格式化电话号码。如果您想要格式化不同的电话号码,请更改变量"phone"的值即可。

6
将10位电话号码显示为美国格式 (###) ###-####。
(SWIFT 3)
func arrangeUSFormat(strPhone : String)-> String {
    var strUpdated = strPhone
    if strPhone.characters.count == 10 {
        strUpdated.insert("(", at: strUpdated.startIndex)
        strUpdated.insert(")", at: strUpdated.index(strUpdated.startIndex, offsetBy: 4))
        strUpdated.insert(" ", at: strUpdated.index(strUpdated.startIndex, offsetBy: 5))
        strUpdated.insert("-", at: strUpdated.index(strUpdated.startIndex, offsetBy: 9))
    }
    return strUpdated
}

5
您不能这样做,因为在Swift中,字符串索引(String.Index)是基于Unicode图形簇定义的,以便它可以很好地处理所有Unicode内容。所以您不能直接从索引构建一个String.Index。您可以使用advance(theString.startIndex, 3)来查看构成字符串的簇并计算对应于第三个簇的索引,但要注意,这是一个O(N)操作。
在您的情况下,使用字符串替换操作可能更容易。
有关更多详细信息,请查看此博客文章

4

这是Dilmurat回答的Swift 4.2版本(带有代码修复)

extension String {
    mutating func insert(string:String,ind:Int) {
        self.insert(contentsOf: string, at:self.index(self.startIndex, offsetBy: ind) )
    }
}

请注意,索引必须与您要插入的字符串(self)对齐,而不是您提供的字符串。

2

在 Swift 2.0 及以下版本中,您无法使用 String,因为在 Swift 2.0 中,String 不再是一个 collection。但在 Swift 3 / 4 中,由于 String 再次成为了 Collection,因此不再需要。请使用 StringCollection 的本地方法。

var stringts:String = "3022513240"
let indexItem = stringts.index(stringts.endIndex, offsetBy: 0)
stringts.insert("0", at: indexItem)
print(stringts) // 30225132400

1

简单易行的方法是将String转换为Array,以便像这样获得索引的好处:

let input = Array(str)

如果您尝试索引String而没有使用任何转换,则会出现错误。
这是扩展的完整代码:
extension String {
    subscript (_ index: Int) -> String {
    
        get {
             String(self[self.index(startIndex, offsetBy: index)])
        }
    
        set {
            if index >= count {
                insert(Character(newValue), at: self.index(self.startIndex, offsetBy: count))
            } else {
                insert(Character(newValue), at: self.index(self.startIndex, offsetBy: index))
            }
        }
    }
}

现在,您可以像最初想要的那样,通过索引从字符串中读取和写入单个字符:

var str = "car"
str[3] = "d"
print(str)

使用它是一种简单而实用的方法,可以轻松地使用Swift的字符串访问模型。现在,当您可以直接循环遍历字符串时,不需要将其转换为Array,您会觉得这非常顺畅。
尝试一下,看看它是否有帮助!

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