获取字符串的长度


781

你怎么得到一个长度String?例如,我有一个定义如下的变量:

var test1: String = "Scott"

但是,我似乎找不到在字符串上的长度方法。



由于Swift 3,我不得不手动迁移大量代码。因此,我决定创建扩展。因此,现在,如果必须升级到新的主要版本,我只需要迁移扩展。在这里,您可以找到我创建的一些Swift 3扩展。github.com/tukur187/Swift3
Shkelzen '16

Answers:


1284

自Swift 4+起

只是:

test1.count

原因。

(感谢Martin R)

从Swift 2开始:

在Swift 2中,Apple已将全局功能更改为协议扩展,这些扩展可与符合协议的任何类型匹配。因此,新语法为:

test1.characters.count

(感谢JohnDifool的注意)

从Swift 1开始

使用计数字符方法:

let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
println("unusualMenagerie has \(count(unusualMenagerie)) characters")
// prints "unusualMenagerie has 40 characters"

直接来自Apple Swift指南

(请注意,对于早于1.2的Swift版本,应countElements(unusualMenagerie)改为)

对于您的变量,它将是

length = count(test1) // was countElements in earlier versions of Swift

或者您可以使用test1.utf16count


11
有趣的是countElements是一个全局函数。有全局功能列表吗?
Scott Walter

7
countElements的麻烦在于它的声明是这样的:func countElements <T>(x:T)-> T.IndexType.DistanceType,并且返回类型不接受+操作。
MarkAurelius 2014年

288
添加str.length方法太困难了。(激怒他的拳头)
botbot

13
使用Swift 2,我只能使它起作用:let len = test1.characters.count
Laurent

7
请注意,对于Swift 4,它将为string.count
马丁R

335

TLDR:

对于Swift 2.0和3.0,请使用test1.characters.count。但是,您应该了解一些事情。因此,继续阅读。

在Swift中计数字符

在Swift 2.0之前,它count是一个全局函数。从Swift 2.0开始,它可以被称为成员函数。

test1.characters.count

它会返回中的Unicode字符的实际数量String,因此,这是最正确的选择,如果您要打印字符串并手动计算字符,则将得到相同的结果。

但是,由于Strings是在Swift中实现的方式,字符并不总是占用相同的内存量,因此请注意,其行为与其他语言中的常规字符计数方法完全不同。

例如,您也可以使用 test1.utf16.count

但是,如下所述,不能保证返回的值与调用counton 相同characters

从语言参考:

扩展字素簇可以由一个或多个Unicode标量组成。这意味着不同的字符(以及同一字符的不同表示形式)可能需要存储不同数量的内存。因此,Swift中的字符在字符串表示中不会各自占用相同数量的内存。结果,如果不迭代字符串以确定其扩展字素簇边界,就无法计算字符串中的字符数。如果使用特别长的字符串值,请注意,characters属性必须遍历整个字符串的Unicode标量,才能确定该字符串的字符。

由characters属性返回的字符数并不总是与包含相同字符的NSString的length属性相同。NSString的长度基于字符串的UTF-16表示形式中16位代码单元的数量,而不是字符串中的Unicode扩展字素簇的数量。

可以很好地说明上述情况的示例是检查包含单个表情符号字符的字符串的长度,如注释中n00neimp0rtant所指出的。

var emoji = "👍"
emoji.characters.count             //returns 1
emoji.utf16.count                  //returns 2

26
感谢您的详细和谨慎的回答,但我必须承认这让我感到不安。您给了我3种方法来获取字符串的长度,但所有这些都否认了它们给出的答案可能不是您所期望的。Swift真的没有可靠的方法可以获取准确,可靠的字符串长度值吗?
n00neimp0rtant

6
@ n00neimp0rtant。对不起,如果我不清楚。第一个解决方案(countElements())获取字符串中确切的字符数。这可能与您[str length]在Objective-C中调用所得到的有所不同,因为该length方法假定字符串中的所有字符均由16位代码单元组成,而countElements()获得的是Unicode字符的实际数量。但是,在大多数情况下,上述所有替代方法都会返回相同的结果,尤其是在使用英语通用字符的情况下。
Cezar 2014年

2
@ n00neimp0rtant我调整了一下答案以使其更加清晰。
Cezar 2014年

2
我明白你的意思了。我只是尝试获取包含单个表情符号字符的字符串的长度;Objective-C给我的值是4,而Swift给我的值是1。因此,它实际上似乎更准确(因此,具有讽刺意味的是,“不是我期望的值” = P)。感谢您的澄清!
n00neimp0rtant

1
确实是@ n00neimp0rtant!这是一个完美的例子。我什至将其添加到答案中
Cezar 2014年

92

Swift 1.2更新:不再有用于计数集合大小的countElements了。只需使用count函数作为替换即可:count(“ Swift”)

Swift 2.0、3.0和3.1:

让strLength = string.characters.count

Swift 4.2(4.0及更高版本):[Apple文档-字符串]

让strLength = string.count


61

斯威夫特1.1

extension String {
    var length: Int { return countElements(self) }  // 
}

斯威夫特1.2

extension String {
    var length: Int { return count(self)         }  // 
}

雨燕2.0

extension String {
    var length: Int { return characters.count    }  // 
}

斯威夫特4.2

extension String {
    var length: Int { return self.count }           
}

let str = "Hello"
let count = str.length    // returns 5 (Int)

6
是的,我们需要一个用于Swift语法的抽象层,该层每月都在变化!
Cosmin

@Lee这在Swift 4.中不起作用,因为不推荐使用字符。狂奔不断。叹息
eonist '17

48

斯威夫特4

"string".count

;)

迅捷3

extension String {
    var length: Int {
        return self.characters.count
    }
}

用法

"string".length


它返回String.CharacterView.IndexDistance。那Int呢?
eonist

@GitSync在哪里?我不了解您
维亚切斯拉夫(Vyacheslav)

@Vyacheslav在swift 4“ string” .count中返回String.CharacterView.IndexDistance在这里查看我的答案:stackoverflow.com/a/47203597/5389500在swift 3和4中获取int
eonist

我已经在操场上测试过:
维亚切斯拉夫(Vyacheslav)

//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground" print(type(of: str.characters.count)) print(type(of: str.count))
Vyacheslav

25

如果您只是想查看字符串是否为空(检查长度是否为0),Swift会提供一个简单的布尔测试方法 String

myString.isEmpty

硬币的另一面是人们在ObjectiveC中问如何在检查长度为0的地方问字符串是否为空:

NSString为空


18

tl; dr如果要以人类可读字符的数量表示String类型的长度,请使用countElements()。如果要根据扩展字素簇的数量知道长度,请使用endIndex。继续阅读以获取详细信息。

字符串型被实现为一个有序集合中的Unicode字符(即,序列),它符合CollectionType协议,这符合_CollectionType协议,它是由所期望的输入类型()countElements。因此,可通过传递String类型来调用countElements(),它将返回字符数。

但是,在遵循CollectionType(又符合_CollectionType)的情况下String还实现了startIndexendIndex计算的属性,它们实际上分别表示第一个字符簇之前的索引位置和最后一个字符簇之后的索引位置。。因此,在字符串“ ABC”中,索引在A之前和C之后的位置是3。因此,endIndex = 3,这也是字符串的长度。

因此,可以使用endIndex来获取任何String类型的长度,对吧?

好吧,并非总是... Unicode字符实际上是扩展的字素簇,它们是一个或多个 Unicode标量的序列,它们组合在一起以创建一个人类可读的字符。

let circledStar: Character = "\u{2606}\u{20DD}" // ☆⃝

circledStar是由U + 2606(白星)和U + 20DD(一个组合的圆圈)组成的单个字符。让我们从circledStar创建一个String并比较countElements()endIndex的结果。

let circledStarString = "\(circledStar)"
countElements(circledStarString) // 1
circledStarString.endIndex // 2

15

在Swift 2.0 count中不再起作用。您可以改用以下方法:

var testString = "Scott"
var length = testString.characters.count

14

这比使用全局函数更短,更自然:

aString.utf16count

我不知道它是否在beta 1中可用。但是肯定在beta 2中。


2
请参阅Cezar的答案。对于大多数人对“字符”的定义,这不一定会为您提供字符串中“字符”的数目。再说一次,Objective-C都没有—由您决定是否在乎。
jbg

12

斯威夫特5.1,5

let flag = "🇵🇷"

print(flag.count)
// Prints "1" --  Counts the characters and emoji as length 1

print(flag.unicodeScalars.count)
// Prints "2" --  Counts the unicode lenght ex. "A" is 65

print(flag.utf16.count)
// Prints "4"

print(flag.utf8.count)
// Prints "8"

11

已针对Xcode 6 beta 4更新,更改方法utf16count-> utf16Count

 var test1: String = "Scott"
 var length =  test1.utf16Count

要么

 var test1: String = "Scott"
 var length = test1.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)

当您使用带有表情符号的复杂字符串时,答案utf16count将是错误的
Victor Sigler 2015年

10

从Swift 1.2开始utf16Count已被删除。现在,您应该使用全局count()函数并传递字符串的UTF16视图。下面的例子

let string = "Some string"
count(string.utf16)

1
它比.utf16count慢吗?
samir105 2015年

1
看来速度与.utf16count相同,但比count(string)快得多
samir105

8

对于Xcode 7.3和Swift 2.2。

let str = "🐶"
  1. 如果需要可视字符数:

    str.characters.count
  2. 如果要“字符串的UTF-16表示形式内的16位代码单元”:

    str.utf16.count

大多数情况下,您需要的是1

什么时候需要2?我发现了2的用例:

let regex = try! NSRegularExpression(pattern:"🐶", 
    options: NSRegularExpressionOptions.UseUnixLineSeparators)
let str = "🐶🐶🐶🐶🐶🐶"
let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.utf16.count), withTemplate: "dog")
print(result) // dogdogdogdogdogdog

如果使用1,则结果不正确:

let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.characters.count), withTemplate: "dog")
print(result) // dogdogdog🐶🐶🐶


6

在Swift 2.x中,以下是如何查找字符串的长度

let findLength = "This is a string of text"
findLength.characters.count

返回24


5

Swift 2.0:获得成功: yourString.text.characters.count

一个有趣的例子是在UITextView中显示某个数字(例如150)倒数的字符:

func textViewDidChange(textView: UITextView) {
    yourStringLabel.text = String(150 - yourStringTextView.text.characters.count)
}

4

在swift4中,我一直使用string.count到今天为止

string.endIndex.encodedOffset

是更好的替代方法,因为它速度更快-对于50000个字符的字符串,比字符串速度快6倍.count。在.count依赖于字符串长度,但.endIndex.encodedOffset没有。

但有一个NO。这对于带有表情符号的字符串不是很好,它会给出错误的结果,因此只有.count正确。


3

Swift 4中:如果字符串不包含Unicode字符,则使用以下命令

let str : String = "abcd"
let count = str.count // output 4

如果字符串包含Unicode字符,则使用以下命令:

let spain = "España"
let count1 = spain.count // output 6
let count2 = spain.utf8.count // output 7

为什么要使用utf8.count?那不算字符数。它给出了字符串的UTF-8编码所需的字节数。
rmaddy19 '19

2

在Xcode 6.1.1中

extension String {    
    var length : Int { return self.utf16Count  }
}

我认为,脑子病患者会在每个次要版本中更改此设置。


2

从您的textview或textfield中获取字符串值:

let textlengthstring = (yourtextview?.text)! as String

查找字符串中的字符数:

let numberOfChars = textlength.characters.count

2

这就是我最终要做的

let replacementTextAsDecimal = Double(string)

if string.characters.count > 0 &&
    replacementTextAsDecimal == nil &&
    replacementTextHasDecimalSeparator == nil {
        return false
}

我认为您正在尝试做更多的事情,而不仅仅是获取字符串的长度,无论如何这看起来都是不完整的(不应该有这种return true情况吗?)。您能否仔细检查一下,以防您修改答案?谢谢!
法比奥说莫妮卡(Reonica Monica)

2

Swift 4更新与Swift 3比较

Swift 4消除了在String上使用字符数组的需要。这意味着您可以直接调用count字符串,而无需先获取字符数组。

"hello".count                  // 5

而在swift 3中,您将必须获取character数组,然后计算该数组中的element。请注意,以下方法在swift 4.0中仍然可用,因为您仍然可以调用characters以访问给定字符串的字符数组

"hello".characters.count       // 5

Swift 4.0还采用Unicode 9,它现在可以解释字素簇。例如,指望表情符号会得到1,而在迅速3.0中,您可能会得到大于1的计数。

"👍🏽".count // Swift 4.0 prints 1, Swift 3.0 prints 2
"👨‍❤️‍💋‍👨".count // Swift 4.0 prints 1, Swift 3.0 prints 4

2

斯威夫特4

let str =  "Your name"

str.count 

切记:数字中也计入空格


2

您可以通过编写扩展名来简单地获取长度:

extension String {
    // MARK: Use if it's Swift 2
    func stringLength(str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 3
    func stringLength(_ str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 4
    func stringLength(_ str: String) -> Int {
        return str.count
    }
}

1
var str = "Hello, playground"
var newString = str as NSString    

countElements(str)

这将计算常规Swift字符串中的字符

countElements((newString as String))    

这计算了NSString中的字符


1

在Swift中计算String的最佳方法是:

var str = "Hello World"
var length = count(str.utf16)

2
您应该只使用count(str)。尝试使用带有子字符串advance()的tu使用count(str.utf16)
Leo Dabus

1

String和NSString是免费的桥梁,因此您可以通过swift String使用NSString可用的所有方法

let x = "test" as NSString
let y : NSString = "string 2"
let lenx = x.count
let leny = y.count


1

苹果公司使其与其他主要语言有所不同。当前方法是调用:

test1.characters.count

但是,要小心,当您说长度时,是指字符数而不是字节数,因为当您使用非ASCII字符时,这两个字符可以不同。

例如; "你好啊hi".characters.count会给你5,但这不是字节数。要获取实际的字节数,您需要执行"你好啊hi".lengthOfBytes(using: String.Encoding.utf8)。这将给您11。


1

现在(在Swift 2.3中),如果您使用:

myString.characters.count 

该方法将返回一个“ Distance”类型,如果您需要该方法返回一个Integer,则应像下面这样键入cast:

var count = myString.characters.count as Int

2
DistanceString.CharacterView Int,应该没有必要为此演员。
马丁R
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.