{"id":21770300,"url":"https://github.com/flight-school/guide-to-swift-strings-sample-code","last_synced_at":"2025-07-19T07:30:35.309Z","repository":{"id":95268954,"uuid":"168718825","full_name":"Flight-School/Guide-to-Swift-Strings-Sample-Code","owner":"Flight-School","description":"Xcode Playground Sample Code for the Flight School Guide to Swift Strings","archived":true,"fork":false,"pushed_at":"2019-05-24T15:57:16.000Z","size":1774,"stargazers_count":148,"open_issues_count":1,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T22:28:03.415Z","etag":null,"topics":["antlr4","binary-to-text","nlp","parser","regex","strings","swift","unicode"],"latest_commit_sha":null,"homepage":"https://flight.school/books/strings","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flight-School.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["mattt"],"custom":"https://flight.school"}},"created_at":"2019-02-01T15:34:09.000Z","updated_at":"2025-03-10T23:15:11.000Z","dependencies_parsed_at":"2023-03-03T23:30:43.974Z","dependency_job_id":null,"html_url":"https://github.com/Flight-School/Guide-to-Swift-Strings-Sample-Code","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Flight-School/Guide-to-Swift-Strings-Sample-Code","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flight-School%2FGuide-to-Swift-Strings-Sample-Code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flight-School%2FGuide-to-Swift-Strings-Sample-Code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flight-School%2FGuide-to-Swift-Strings-Sample-Code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flight-School%2FGuide-to-Swift-Strings-Sample-Code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flight-School","download_url":"https://codeload.github.com/Flight-School/Guide-to-Swift-Strings-Sample-Code/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flight-School%2FGuide-to-Swift-Strings-Sample-Code/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265900799,"owners_count":23845992,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["antlr4","binary-to-text","nlp","parser","regex","strings","swift","unicode"],"created_at":"2024-11-26T14:12:07.490Z","updated_at":"2025-07-19T07:30:35.282Z","avatar_url":"https://github.com/Flight-School.png","language":"Swift","readme":"\u003ca href=\"https://flight.school/books/strings\"\u003e\n    \u003cimg src=\"cover.jpg\" alt=\"Flight School Guide to Swift Strings Cover\" title=\"Flight School Guide to Swift Strings\" width=\"216\" height=\"332\" align=\"right\"\u003e\n\u003c/a\u003e\n\n# Guide to Swift Strings Sample Code\n\n[![Build Status][build status badge]][build status]\n[![License][license badge]][license]\n[![Swift Version][swift version badge]][swift version]\n\nThis repository contains sample code used in the\n[Flight School Guide to Swift Strings](https://flight.school/books/strings).\n\n---\n\n- [Chapter 2: Working with Strings in Swift](#chapter-2)\n- [Chapter 3: Swift String Protocols and Supporting Types](#chapter-3)\n- [Chapter 4: Working with Foundation String APIs](#chapter-4)\n- [Chapter 5: Binary-to-Text Encoding](#chapter-5)\n- [Chapter 6: Parsing Data From Text](#chapter-6)\n- [Chapter 7: Natural Language Processing](#chapter-7)\n\n---\n\n## Chapter 2\n\n### String Literals\n\nYou can construct string values in Swift using string literals.\nThis Playground has examples of each variety,\nfrom the conventional, single-line to the raw, multi-line.\n\n```swift\nlet multilineRawString = #\"\"\"\n \\-----------------------\\\n  \\                       \\\n   \\      ___              \\\n    \\    (_  /'_ /_/        \\        __\n     \\   /  (/(//)/          \\       | \\\n      \u003e      _/               \u003e------|  \\       ______\n     /     __                /       --- \\_____/**|_|_\\____  |\n    /     (  _ /     /      /          \\_______ --------- __\u003e-}\n   /     __)( /)()()(      /              /  \\_____|_____/   |\n  /                       /               *         |\n /-----------------------/                         {o}\n\"\"\"#\n```\n\n### String Indexes\n\nSwift strings have opaque index types.\nOne consequence of this is that\nyou can't access character by integer position directly,\nas you might in other languages.\nThis Playground shows various strategies for\nworking with string indices and ranges.\n\n```swift\nlet string = \"Hello\"\n\nstring[string.startIndex] // \"H\"\nstring[string.index(after: string.startIndex)] // \"e\"\nstring[string.index(string.startIndex, offsetBy: 4)] // \"o\"\n```\n\n### Canonical Equivalence\n\nIn Swift,\ntwo `String` values are considered equal if they are\n\u003cdfn\u003e[canonically equivalent](http://unicode.org/notes/tn5/)\u003c/dfn\u003e,\neven if they comprise different Unicode scalar values.\n\n```swift\nlet precomposed = \"expos\\u{00E9}\" // é LATIN SMALL LETTER E WITH ACUTE\nlet decomposed = \"expose\\u{0301}\" // ´ COMBINING ACUTE ACCENT\n\nprecomposed == decomposed\nprecomposed.elementsEqual(decomposed) // true\n\nprecomposed.unicodeScalars.elementsEqual(decomposed.unicodeScalars) // false\n```\n\n### Unicode Views\n\nSwift `String` values\nprovide views to their UTF-8, UTF-16, and UTF-32 code units.\nThis Playground shows the correspondence between\nthe characters in a string and their various encoding forms.\n\n```swift\nlet string = \"東京 🇯🇵\"\nfor unicodeScalar in character.unicodeScalars {\n    print(unicodeScalar.codePoint, terminator: \"\\t\")\n}\n```\n\n### Character Number Values\n\nIn Swift 5,\nyou can access several Unicode properties of `Character` values,\nwhich allow you to determine things like\nUnicode general category membership,\nwhether a character has case mapping (lowercase / uppercase / titlecase),\nand whether the character has an associated number value.\n\n```swift\n// U+2460 CIRCLED DIGIT ONE\n(\"①\" as Character).isNumber // true\n(\"①\" as Character).isWholeNumber // true\n(\"①\" as Character).wholeNumberValue // 1\n```\n\n### Emoji Detection\n\nFor more direct access to the aforementioned character information,\nyou can do so through the `properties` property on `Unicode.Scalar` values.\nFor example,\nthe `isEmoji` property does...\nwell, exactly what you'd expect it to do.\n\n```swift\n(\"👏\" as Unicode.Scalar).properties.isEmoji // true\n```\n\n## Chapter 3\n\n### String as **\\*\\***\\_\\_\\_**\\*\\***\n\nIn Swift,\n`String` functionality is inherited from\na complex hierarchy of interrelated protocols,\nincluding\n`Sequence`,\n`Collection`,\n`BidirectionalCollection`,\n`RangeReplaceableCollection`,\n`StringProtocol`,\nand others.\n\nEach of the protocols mentioned has their own Playground\ndemonstrating the specific functionality they provide.\n\n```swift\n\"Boeing 737-800\".filter { $0.isCased }\n                .map { $0.uppercased() }\n[\"B\", \"O\", \"E\", \"I\", \"N\", \"G\"]\n```\n\n### Unicode Logger\n\nThe `print` function can direct its output\nto a custom type conforming to the `TextOutputStream` protocol.\nThis example implements a logger\nthat prints the Unicode code points of the provided string.\n\n```swift\nvar logger = UnicodeLogger()\nprint(\"👨‍👩‍👧‍👧\", to: \u0026logger)\n\n// 0: 👨 U+1F468\tMAN\n// 1: ‍ U+200D\tZERO WIDTH JOINER\n// 2: 👩 U+1F469\tWOMAN\n// 3: ‍ U+200D\tZERO WIDTH JOINER\n// 4: 👧 U+1F467\tGIRL\n// 5: ‍ U+200D\tZERO WIDTH JOINER\n// 6: 👧 U+1F467\tGIRL\n```\n\n### Stderr Output Stream\n\nText output streams can also be used to\ndirect print statements from the default `stdout` destination.\nIn this example,\nthe `print` function is directed to write to `stderr`.\n\n```swift\nvar standardError = StderrOutputStream()\nprint(\"Error!\", to: \u0026standardError)\n```\n\n### Booking Class\n\nSwift allows any type that conforms to `ExpressibleByStringLiteral`\nto be initialized from a string literal.\nThis Playground provides a simple example through the `BookingClass` type.\n\n```swift\n(\"J\" as BookingClass) // Business Class\n```\n\n### Flight Code\n\nTypes conforming to the `LosslessStringConvertible` protocol\ncan be initialized directly from `String` values.\nThis Playground shows a `FlightCode` type that adopts both\nthe `LosslessStringConvertible` and `ExpressibleByStringLiteral` protocols.\n\n```swift\nlet flight: FlightCode = \"AA 1\"\n\nflight.airlineCode\nflight.flightNumber\n\nFlightCode(String(flight))\n```\n\n### Unicode Styling\n\nSwift 5 makes it possible to customize\nthe behavior of interpolation in string literals\nby way of the `ExpressibleByStringInterpolation` protocol.\nTo demonstrate this,\nwe implement a `StyledString` type that\nallows interpolation segments to specify a style,\nsuch as **bold**, _italic_, and 𝔣𝔯𝔞𝔨𝔱𝔲𝔯.\n\n```swift\nlet name = \"Johnny\"\nlet styled: StyledString = \"\"\"\nHello, \\(name, style: .fraktur(bold: true))!\n\"\"\"\n\nprint(styled)\n```\n\n## Chapter 4\n\n### Range Conversion\n\nObjective-C APIs that take `NSString` parameters\nor have `NSString` return values\nare imported by Swift to use `String` values instead.\nHowever, some of these APIs still specify ranges using the `NSRange` type\ninstead of `Range\u003cString.Index\u003e`.\nThis Playground demonstrates how to convert back and forth\nbetween the two range types.\n\n```swift\nimport Foundation\n\nlet string = \"Hello, world!\"\nlet nsRange = NSRange(string.startIndex..\u003cstring.endIndex, in: string)\nlet range = Range(nsRange, in: string)\n```\n\n### Localized String Operations\n\nFoundation augments the Swift `String` type\nby providing localized string operations,\nincluding\ncase mapping,\nsearching,\nand comparison.\nBe sure to use localized string operations\n(ideally, the `standard` variant, if applicable)\nwhen working with text written or read by users.\n\n```swift\nimport Foundation\n\n\"Éclair\".contains(\"E\") // false\n\"Éclair\".localizedStandardContains(\"E\") // true\n```\n\n### Numeric String Sorting\n\nAnother consideration for localized string sorting is how to handle numbers.\nBy default, strings sort digits lexicographically;\n7 follows 3, but 7 also follows 36.\nThis Playground demonstrates proper use of the\n`localizedStandardCompare` comparator,\nwhich is what Finder uses to sort filenames.\n\n```swift\nimport Foundation\n\nlet files: [String] = [\n    \"File 3.txt\",\n    \"File 7.txt\",\n    \"File 36.txt\"\n]\n\nlet order: ComparisonResult = .orderedAscending\n\nfiles.sorted { lhs, rhs in\n    lhs.localizedStandardCompare(rhs) == order\n}\n// [\"File 3.txt\", \"File 7.txt\", \"File 36.txt\"]\n```\n\n### Normalization Forms\n\nFoundation provides APIs for accessing normalization forms for strings,\nincluding NFC and NFD,\nas demonstrated in this example.\n\n```swift\nimport Foundation\n\nlet string = \"ümlaut\"\n\nlet nfc = string.precomposedStringWithCanonicalMapping\nnfc.unicodeScalars.first\n\nlet nfd = string.decomposedStringWithCanonicalMapping\nnfd.unicodeScalars.first\n```\n\n### String Encoding Conversion\n\nFoundation offers support for many different legacy string encodings,\nas shown in this example.\n\n```swift\nimport Foundation\n\n\"Hello, Macintosh!\".data(using: .macOSRoman)\n```\n\n### String from Data\n\nFoundation provides APIs to read and write `String` values\nfrom data values and files.\n\n```swift\nimport Foundation\n\nlet url = Bundle.main.url(forResource: \"file\", withExtension: \"txt\")!\ntry String(contentsOf: url) // \"Hello!\"\n\nlet data = try Data(contentsOf: url)\nString(data: data, encoding: .utf8) // \"Hello!\"\n```\n\n### String Transformation\n\nAnother cool bit of functionality `String` inherits from `NSString`\nis the ability to apply\n[ICU string transforms](http://userguide.icu-project.org/transforms/general),\nas seen in this example.\n\n```swift\nimport Foundation\n\n\"Avión\".applyingTransform(.stripDiacritics, reverse: false)\n// \"Avion\"\n\n\"©\".applyingTransform(.toXMLHex, reverse: false)\n// \"\u0026#xA9;\"\n\n\"🛂\".applyingTransform(.toUnicodeName, reverse: false)\n// \"\\\\N{PASSPORT CONTROL}\"\n\n\"マット\".applyingTransform(.fullwidthToHalfwidth, reverse: false)\n// \"ﾏｯﾄ\"\n```\n\n### Trimming\n\nFoundation's `CharacterSet` is used in various string APIs,\nbut it's perhaps most well-known for its role in the\n`trimmingCharacters(in:)` method,\nas shown in this Playground.\n\n```swift\nimport Foundation\n\n\"\"\"\n\n            ✈️\n\n\"\"\".trimmingCharacters(in: .whitespacesAndNewlines) // \"✈️\"\n```\n\n### URL Encoding\n\nOnly certain characters are allowed in certain positions of a URLs.\nBy importing Foundation,\nyou can encode URL query parameters with confidence\nwith the `addingPercentEncoding(withAllowedCharacters:)` method.\n\n```swift\nimport Foundation\n\n\"q=lax to jfk\".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)\n// q=lax%20to%20jfk\n```\n\n### String Format\n\nWhen you import the Foundation framework,\n`String` gets `sprintf`-style initializers.\nThis Playground serves as an exhaustive reference\nfor all of the available\nformatting specifiers, modifiers, flags, and arguments.\n\n```swift\nimport Foundation\n\nString(format: \"%X\", 127) // \"7F\"\n```\n\n## Chapter 5\n\n### Base2 and Base16 Encoding\n\nThese examples show you how to\nuse the `String(_:radix:uppercase:)` initializer to\nproduce binary and hexadecimal representations of binary integer values.\n\n```swift\nlet byte: UInt8 = 0xF0\n\nString(byte, radix: 2) // \"11110000\"\nString(byte, radix: 16, uppercase: true) // \"F0\"\n```\n\n### Base64 Encoding\n\nFoundation provides APIs for base64 encoding and decoding data,\nwhich are demonstrated in this Playground.\n\n```swift\nimport Foundation\n\nlet string = \"Hello!\"\n\nlet data = string.data(using: .utf8)!\nlet encodedString = data.base64EncodedString() // \"SGVsbG8h\"\n```\n\n### Base🧑 Encoding\n\nAnticipating emoji's role in the forthcoming collapse of human communication,\nwe present a novel binary-to-text encoding format\nthat represents data using human face emoji\ncombined with skin tone and hair style modifiers.\n\n```swift\nlet data = \"Fly\".data(using: .utf8)!\nlet encodedString = data.base🧑EncodedString() // \"👨🏽‍🦱👩🏻‍🦲👩🏽‍🦳👩🏿‍🦱\"\n```\n\n### Human Readable Encoding\n\nIn this example,\nwe implement the 11-bit binary-to-text encoding described in\n[RFC 1751](https://tools.ietf.org/html/rfc1751):\n\"A Convention for Human-Readable 128-bit Keys\".\n_\"Why?\"_ you ask?\n_Why indeed!_\n\n```swift\nimport Foundation\n\nlet data = Data(bytes: [0xB2, 0x03, 0xE2, 0x8F,\n                        0xA5, 0x25, 0xBE, 0x47])\n\ndata.humanReadableEncodedString()\n// \"LONG IVY JULY AJAR BOND LEE\"\n```\n\n## Chapter 6\n\n### Parsing with Scanner\n\nOne of Foundation's many offerings is the `Scanner` class:\na sort of lexer/parser combo deal with some convenient features.\nThis Playground demonstrates how to make it even more convenient in Swift,\nand how to use it to parse information from an AFTN message.\n\n```swift\nimport Foundation\n\nlet scanner = Scanner(string: string)\nscanner.charactersToBeSkipped = .whitespacesAndNewlines\n\ntry scanner.scan(\"ZCZC\")\nlet transmission = try scanner.scan(.alphanumerics)\nlet additionalServices = try scanner.scan(.decimalDigits)\nlet priority = try scanner.scan(.uppercaseLetters)\nlet destination = try scanner.scan(.uppercaseLetters)\nlet time = try scanner.scan(.decimalDigits)\nlet origin = try scanner.scan(.uppercaseLetters)\nlet text = try scanner.scan(upTo: \"NNNN\")\n```\n\n### Parsing with Regular Expressions\n\nFoundation's `NSRegularExpression` offers the closest thing to\nbuilt-in regex support in Swift.\nUnderneath the hood, it wraps the\n[ICU regular expression engine](http://userguide.icu-project.org/strings/regexp);\nwe take advantage of a bunch of its advanced features in this Playground\nto parse the same message as before using a different approach.\n\n```swift\nimport Foundation\n\nlet pattern = #\"\"\"\n(?x-i)\n\\A\nZCZC \\h\n(?\u003ctransmission\u003e[A-Z]{3}[0-9]{3}) \\h (?\u003cadditionalService\u003e[0-9]{0,8}) \\n\n(?\u003cpriority\u003e[A-Z]{2}) \\h (?\u003cdestination\u003e[A-Z]{8}) \\n\n(?\u003ctime\u003e[0-9]{6}) \\h (?\u003corigin\u003e[A-Z]{8}) \\n+\n(?\u003ctext\u003e[[A-Z][0-9]\\h\\n]+) \\s*\nNNNN\n\\Z\n\"\"\"#\n\nlet regex = try NSRegularExpression(pattern: pattern,\n                                    options: [])\n```\n\n### Parsing with ANTLR4\n\n[ANTLR](https://www.antlr.org) is a parser generator\nwith support for Swift code generation.\nThis example provides a functional integration between ANTLR4\nand the Swift Package Manager to demonstrate yet another approach\nto parsing the same AFTN message from the previous examples.\n\n```swift\nimport AFTN\n\nlet message = try Message(string)!\nmessage.priority\nmessage.destination.location\nmessage.destination.organization\nmessage.destination.department\nmessage.filingTime\nmessage.text\n```\n\n## Chapter 7\n\n### Tokenization\n\nThe NaturalLanguage framework's `NLTokenizer` class\ncan tokenize text by word, sentence, and paragraph,\nas demonstrated in this example.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"Welcome to New York, where the local time is 9:41 AM.\"\nlet tokenizer = NLTokenizer(unit: .word)\ntokenizer.string = string\n\nlet stringRange = string.startIndex..\u003cstring.endIndex\ntokenizer.enumerateTokens(in: stringRange) { (tokenRange, _) in\n    let token = string[tokenRange]\n    print(token, terminator: \"\\t\")\n    return true // continue processing\n}\n// Prints: \"Welcome\tto\tNew\tYork\twhere\tthe\tlocal\ttime\tis\t9\t41\tAM\t\"\n```\n\n### Language Tagging\n\nYou can use the `NLTagger` class to detect the language and script\nfor a piece of natural language text,\nas seen in this Playground.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"\"\"\nSehr geehrte Damen und Herren,\nherzlich willkommen in Frankfurt.\n\"\"\"\n\nlet tagSchemes: [NLTagScheme] = [.language, .script]\nlet tagger = NLTagger(tagSchemes: tagSchemes)\ntagger.string = string\n\nfor scheme in tagSchemes {\n    if case let (tag?, _) = tagger.tag(at: string.startIndex,\n                                       unit: .word,\n                                       scheme: scheme) {\n        print(scheme.rawValue, tag.rawValue)\n    }\n}\n// Prints:\n// \"Language de\"\n// \"Script Latn\"\n```\n\n### Part of Speech Tagging\n\nTo tag part of speech for words (noun, verb, etc.)\nuse the `NLTagger` class with the `.lexicalClass` tag scheme.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"The sleek white jet soars over the hazy fog.\"\n\nlet tagger = NLTagger(tagSchemes: [.lexicalClass])\ntagger.string = string\n\nlet stringRange = string.startIndex..\u003cstring.endIndex\n\nlet options: NLTagger.Options = [.omitWhitespace, .omitPunctuation]\ntagger.enumerateTags(in: stringRange,\n                     unit: .word,\n                     scheme: .lexicalClass,\n                     options: options) { (tag, tagRange) in\n    if let partOfSpeech = tag?.rawValue {\n        print(\"\\(string[tagRange]): \\(partOfSpeech)\")\n    }\n\n    return true // continue processing\n}\n// Prints:\n// \"The: Determiner\"\n// \"sleek: Adjective\"\n// \"white: Adjective\"\n// \"jet: Noun\"\n// ...\n```\n\n### Named Entity Recognition\n\n`NLTagger` can also be used to detect named entities,\nincluding people, places, and organizations.\nThis example shows how to do just that.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"\"\"\nFang Liu of China is the current Secretary General of ICAO.\n\"\"\"\n\nlet tagger = NLTagger(tagSchemes: [.nameType])\ntagger.string = string\n\nlet stringRange = string.startIndex..\u003cstring.endIndex\n\nlet options: NLTagger.Options = [.omitWhitespace, .omitPunctuation, .joinNames]\ntagger.enumerateTags(in: stringRange,\n                     unit: .word,\n                     scheme: .nameType,\n                     options: options) { (tag, tagRange) in\n    if let nameType = tag?.rawValue, tag != .otherWord {\n        print(\"\\(string[tagRange]): \\(nameType)\")\n    }\n\n    return true // continue processing\n}\n// Prints:\n// \"Fang Liu: PersonalName\"\n// \"China: PlaceName\"\n// \"ICAO: OrganizationName\"\n```\n\n### Keyword Extraction\n\nShort of implementing a more complete natural language parser,\nyou can use `NLTagger` to extract keywords by part of speech\nas a first approximation for interpreting commands.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"What's the current temperature in Tokyo?\"\n\nlet tagger = NLTagger(tagSchemes: [.nameTypeOrLexicalClass])\ntagger.string = string\n\nvar taggedKeywords: [(NLTag, String)] = []\n\nlet stringRange = string.startIndex..\u003cstring.endIndex\nlet options: NLTagger.Options = [.omitWhitespace,\n                                 .omitPunctuation,\n                                 .joinNames]\ntagger.enumerateTags(in: stringRange,\n                     unit: .word,\n                     scheme: .nameTypeOrLexicalClass,\n                     options: options) { (tag, tagRange) in\n    guard let tag = tag else { return true }\n    switch tag {\n    case .noun, .placeName:\n        print(tag.rawValue, String(string[tagRange]))\n    default:\n        break\n    }\n\n    return true // continue processing\n}\n// Prints:\n// \"Noun temperature\"\n// \"PlaceName Tokyo\"\n```\n\n### Lemmatization\n\nThis example demonstrates the `.lemma` tag scheme\nand how it resolves conjugations of various words.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"\"\"\nFlying flights fly flyers flown.\n\"\"\"\n\nlet tagger = NLTagger(tagSchemes: [.lemma])\ntagger.string = string\n\ntagger.enumerateTags(in: string.startIndex..\u003cstring.endIndex,\n                     unit: .word,\n                     scheme: .lemma,\n                     options: []) { (tag, tagRange) in\n    if let lemma = tag?.rawValue {\n        print(\"\\(string[tagRange]): \\(lemma)\")\n    }\n\n    return true // continue processing\n}\n// Prints:\n// \"Flying: fly\"\n// \"flights: flight\"\n// \"fly: fly\"\n// \"flyers: flyer\"\n// \"flown: fly\"\n```\n\n### Language Recognizer\n\nThe `NLLanguageRecognizer` provides a configurable classifier\nfor determining the language used in a piece of text.\nHere, we demonstrate how to use the `languageHints` property\nto resolve a sentence that could be understood in either\nNorwegian Bokmål (`nb`) or Danish (`da`).\n\n```swift\nimport NaturalLanguage\n\nlet string = \"\"\"\nGod morgen mine damer og herrer.\n\"\"\"\n\nlet languageRecognizer = NLLanguageRecognizer()\nlanguageRecognizer.processString(string)\n\nlanguageRecognizer.dominantLanguage // da\n\nlanguageRecognizer.languageHints = [.norwegian: 0.75,\n                                    .swedish: 0.25]\n\nlanguageRecognizer.dominantLanguage // nb\n```\n\n### Naive Bayes Classifier\n\nThis example provides a reference implementation for a\nNaive Bayes \"bag of words\" classifier in Swift.\n\n```swift\nenum Sentiment: String, Hashable {\n    case positive, negative\n}\n\nlet classifier = NaiveBayesClassifier\u003cSentiment, String\u003e()\nclassifier.trainText(\"great flight\", for: .positive)\nclassifier.trainText(\"flight was late and turbulent\", for: .negative)\n\nclassifier.classifyText(\"I had a great flight\") // positive\n```\n\n### Sentiment Classification\n\nUsing Create ML, we can build a Core ML classifier model\nthat can be used by the Natural Language framework\nto determine if a piece of natural language text expresses\npositive, negative, or neutral sentiment.\n\n```swift\nimport NaturalLanguage\n\nlet url = Bundle.main.url(forResource: \"SentimentClassifier\",\n                          withExtension: \"mlmodelc\")!\nlet model = try NLModel(contentsOf: url)\n\nmodel.predictedLabel(for: \"Nice, smooth flight\") // positive\n```\n\n### N-Grams\n\nThis Playground provides a Swift implementation of n-grams,\nwhich, combined with `NLTokenizer`,\ncan produce bigrams and trigrams of words in a piece of natural language text.\n\n```swift\nimport NaturalLanguage\n\nlet string = \"\"\"\nPlease direct your attention to flight attendants\nas we review the safety features of this aircraft.\n\"\"\"\n\nlet tokenizer = NLTokenizer(unit: .word)\ntokenizer.string = string\nlet words = tokenizer.tokens(for: string.startIndex..\u003cstring.endIndex)\n                     .map { String(string[$0]) }\nbigrams(words)\n// [(\"Please\", \"direct\"), (\"direct\", \"your\"), ...]\n```\n\n### Markov Chain\n\nUsing n-grams to determine the conditional probability of\ntransitions from one word to another,\nwe can construct a model that randomly generates text\nthat trivially resembles the provided source.\nIn this example,\nwe feed in a corpus of Air Traffic Control transcripts.\n\n```swift\nimport Foundation\nimport NaturalLanguage\n\n// https://catalog.ldc.upenn.edu/LDC94S14A\nlet url = Bundle.main.url(forResource: \"LDC94S14A-sample\",\n                          withExtension: \"txt\")!\nlet text = try String(contentsOf: url)\nvar markovChain = MarkovChain(sentencesAndWords(for: text))\n\nfor word in markovChain {\n    print(word, terminator: \" \")\n}\n\n// Prints: \"CACTUS EIGHT OH EIGHT TURN LEFT HEADING ONE SEVENTY HEAVY\"\n```\n\n### Soundex\n\nSoundex is a classic phonetic coding system\nused to resolve ambiguity in the spelling of surnames.\nThis example provides a Swift implementation of the standard algorithm.\n\n```swift\nlet names: [String] = [\n    \"Washington\",\n    \"Lee\",\n    \"Smith\",\n    \"Smyth\"\n]\n\nfor name in names {\n    print(\"\\(name): \\(soundex(name))\")\n}\n// Prints:\n// \"Washington: W252\"\n// \"Lee: L000\"\n// \"Smith: S530\"\n// \"Smyth: S530\"\n```\n\n### Levenshtein Distance\n\nYou can use a string metric like Levenshtein edit distance\nto quantify the similarity between two sequences.\n\n```swift\n/*\n |     |     |  S  |  a  |  t  |  u  |  r  |  d  |  a  |  y  |\n |-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|\n |     | _0_ |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |\n |   S |  1  | _0_ | _1_ | _2_ |  3  |  4  |  5  |  6  |  7  |\n |   u |  2  |  1  |  1  |  2  | _2_ |  3  |  4  |  5  |  6  |\n |   n |  3  |  2  |  2  |  2  |  3  | _3_ |  4  |  5  |  6  |\n |   d |  4  |  3  |  3  |  3  |  3  |  4  | _3_ |  4  |  5  |\n |   a |  5  |  4  |  3  |  4  |  4  |  4  |  4  | _3_ |  4  |\n |   y |  6  |  5  |  4  |  4  |  5  |  5  |  5  |  4  | _3_ |\n*/\nlevenshteinDistance(from: \"Saturday\", to: \"Sunday\") // 3\n```\n\n### Spell Checker\n\nUsing the Levenshtein distance function from the previous example,\nand combining it with a corpus of frequently-used words,\nyou can create a reasonably effective spell checker\nwith very little additional code.\n\n```swift\nimport Foundation\n\n// https://catalog.ldc.upenn.edu/LDC2006T13\nguard let url = Bundle.main.url(forResource: \"LDC2006T13-sample\",\n                                withExtension: \"txt\")\nelse {\n    fatalError(\"Missing required resource\")\n}\n\nlet spellChecker = try SpellChecker(contentsOf: url)\n\nspellChecker.suggestions(for: \"speling\")\n// [\"spelling\", \"spewing\", \"sperling\"]\n```\n\n---\n\n## License\n\nMIT\n\n## About Flight School\n\nFlight School is a book series for advanced Swift developers\nthat explores essential topics in iOS and macOS development\nthrough concise, focused guides.\n\nIf you'd like to get in touch,\nfeel free to [message us on Twitter](https://twitter.com/flightdotschool)\nor email us at \u003cinfo@flight.school\u003e.\n\n[build status]: https://travis-ci.org/Flight-School/Guide-to-Swift-Strings-Sample-Code\n[build status badge]: https://api.travis-ci.com/Flight-School/Guide-to-Swift-Strings-Sample-Code.svg?branch=master\n[license]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license badge]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[swift version]: https://swift.org/download/\n[swift version badge]: http://img.shields.io/badge/swift%20version-5.0-orange.svg?style=flat\n","funding_links":["https://github.com/sponsors/mattt","https://flight.school"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflight-school%2Fguide-to-swift-strings-sample-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflight-school%2Fguide-to-swift-strings-sample-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflight-school%2Fguide-to-swift-strings-sample-code/lists"}