{"id":13732530,"url":"https://github.com/JohnSundell/Sweep","last_synced_at":"2025-05-08T07:30:49.973Z","repository":{"id":63913151,"uuid":"179502401","full_name":"JohnSundell/Sweep","owner":"JohnSundell","description":"Fast and powerful Swift string scanning made simple","archived":false,"fork":false,"pushed_at":"2020-01-29T11:31:22.000Z","size":65,"stargazers_count":532,"open_issues_count":0,"forks_count":18,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-01T19:43:39.378Z","etag":null,"topics":["scanning","string-parsing","string-scanning","strings","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JohnSundell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-04T13:25:01.000Z","updated_at":"2025-02-04T16:14:47.000Z","dependencies_parsed_at":"2023-01-14T13:15:59.966Z","dependency_job_id":null,"html_url":"https://github.com/JohnSundell/Sweep","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnSundell%2FSweep","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnSundell%2FSweep/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnSundell%2FSweep/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnSundell%2FSweep/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JohnSundell","download_url":"https://codeload.github.com/JohnSundell/Sweep/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253020696,"owners_count":21841622,"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":["scanning","string-parsing","string-scanning","strings","swift"],"created_at":"2024-08-03T02:02:01.714Z","updated_at":"2025-05-08T07:30:49.710Z","avatar_url":"https://github.com/JohnSundell.png","language":"Swift","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"Logo.png\" width=\"500\" max-width=\"90%\" alt=\"Sweep\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-5.0-orange.svg\" /\u003e\n    \u003ca href=\"https://swift.org/package-manager\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=flat\" alt=\"Swift Package Manager\" /\u003e\n    \u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/platforms-mac+linux-brightgreen.svg?style=flat\" alt=\"Mac + Linux\" /\u003e\n    \u003ca href=\"https://twitter.com/johnsundell\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/twitter-@johnsundell-blue.svg?style=flat\" alt=\"Twitter: @johnsundell\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nWelcome to **Sweep** — a powerful and fast, yet easy to use, Swift string scanning library. Scan any string for substrings appearing between two sets of characters — for example to parse out identifiers or metadata from a string of user-defined text.\n\nSweep can be dropped into a project as a general-purpose string scanning algorithm, or act as the base for custom, more high-level scanning implementations. It aims to complement the Swift standard library’s built-in string handling APIs, both in terms of its design, and also how its implemented in an efficient way in line with Swift’s various string conventions.\n\n## Examples\n\nThe easiest way to start using Sweep is to call the `substrings` method that it adds on top of `StringProtocol` — meaning that you can use it on both “normal” strings and `Substring` values.\n\nHere’s an example in which we scan a string for HTML tags, and both identify the names of all tags that appear in the string, and also any text that should be rendered in bold:\n\n```swift\nimport Sweep\n\nlet html = \"\u003cp\u003eHello, \u003cb\u003ethis is bold\u003c/b\u003e, right?\u003c/p\u003e\"\nlet tags = html.substrings(between: \"\u003c\", and: \"\u003e\")\nprint(tags) // [\"p\", \"b\", \"/b\", \"/p\"]\n\nlet boldText = html.substrings(between: \"\u003cb\u003e\", and: \"\u003c/b\u003e\")\nprint(boldText) // [\"this is bold\"]\n```\n\nSweep can also scan for different patterns, such as a prefix appearing at the start of the scanned string, or its end. Here we’re using those capabilities to identify headings in a string of Markdown-formatted text:\n\n```swift\nimport Sweep\n\nlet markdown = \"\"\"\n## Section 1\n\nText\n\n## Section 2\n\"\"\"\n\nlet headings = markdown.substrings(between: [.prefix(\"## \"), \"\\n## \"],\n                                   and: [.end, \"\\n\"])\n\nprint(headings) // [\"Section 1\", \"Section 2\"]\n```\n\nSince Sweep was designed to fit right in alongside Swift’s built-in string APIs, it lets us compose more powerful string scanning algorithms using both built-in functionality and the APIs that Sweep adds — such as here where we’re parsing out an array of tags from a string written using a custom syntax:\n\n```swift\nimport Sweep\n\nlet text = \"{{tags: swift, programming, xcode}}\"\nlet tagStrings = text.substrings(between: \"{{tags: \", and: \"}}\")\nlet tags = tagStrings.flatMap { $0.components(separatedBy: \", \") }\nprint(tags) // [\"swift\", \"programming\", \"xcode\"]\n```\n\nSweep was also designed to be highly efficient, and only makes a single pass through each string that it scans — regardless of how many different patterns you wish to scan for. In this example, we’re using two custom matchers to parse two pieces of metadata from a string:\n\n```swift\nimport Sweep\n\nlet text = \"\"\"\nurl: https://swiftbysundell.com\ntitle: Swift by Sundell\n\"\"\"\n\nvar urls = [URL]()\nvar titles = [String]()\n\ntext.scan(using: [\n    Matcher(identifiers: [\"url: \"], terminators: [\"\\n\", .end]) { match, range in\n        let string = String(match)\n        let url = URL(string: string)\n        url.flatMap { urls.append($0) }\n    },\n    Matcher(identifiers: [\"title: \"], terminators: [\"\\n\", .end]) { match, range in\n        let string = String(match)\n        titles.append(string)\n    }\n])\n\nprint(urls) // [https://swiftbysundell.com]\nprint(titles) // [\"Swift by Sundell\"]\n```\n\nSweep is not only efficient in terms of complexity, it also has a very low memory overhead, thanks to it being built according to Swift’s modern string conventions — making full use of types like `Substring` and `String.Index`, and avoiding unnecessary copying and mutations when performing its scanning.\n\n## Installation\n\nSweep is distributed as a Swift package, and it’s recommended to install it using [the Swift Package Manager](https://github.com/apple/swift-package-manager), by declaring it as a dependency in your project’s `Package.swift` file:\n\n```\n.package(url: \"https://github.com/JohnSundell/Sweep\", from: \"0.1.0\")\n```\n\nFor more information, please see the [Swift Package Manager documentation](https://github.com/apple/swift-package-manager/tree/master/Documentation).\n\n## Contributions \u0026 support\n\nSweep is developed completely in the open, and your contributions are more than welcome.\n\nBefore you start using Sweep in any of your projects, it’s highly recommended that you spend a few minutes familiarizing yourself with its documentation and internal implementation (it all fits [in a single file](https://github.com/JohnSundell/Sweep/blob/master/Sources/Sweep/Sweep.swift)!), so that you’ll be ready to tackle any issues or edge cases that you might encounter.\n\nTo learn more about the principles used to implement Sweep, check out *[“String parsing in Swift”](https://www.swiftbysundell.com/posts/string-parsing-in-swift)* on Swift by Sundell.\n\nSweep does not come with GitHub Issues-based support, and users are instead encouraged to become active participants in its continued development — by fixing any bugs that they encounter, or improving the documentation wherever it’s found to be lacking.\n\nIf you wish to make a change, [open a Pull Request](https://github.com/JohnSundell/Sweep/pull/new) — even if it just contains a draft of the changes you’re planning, or a test that reproduces an issue — and we can discuss it further from there.\n\nHope you enjoy using Sweep! 😀\n","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJohnSundell%2FSweep","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJohnSundell%2FSweep","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJohnSundell%2FSweep/lists"}