Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Swift:获得字符串的子字符串,忽略大小写和重音

Swift:获得字符串的子字符串,忽略大小写和重音
EN

Stack Overflow用户
提问于 2021-02-22 06:29:35
回答 2查看 329关注 0票数 0

我想从字符串中提取子字符串,忽略重音和大小写。

例如,如果字符串为Curaçao,而输入子字符串为aca,则将字符串拆分为三个子字符串:Cur (匹配子字符串之前的子字符串)、aça (匹配子字符串)和o (匹配子字符串之后的剩余子字符串)。

我试过这个代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extension String {
    subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
    subscript(range: Range<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
    
    func highlight(substring: String) -> String {
        if let range = lowercased()
            .folding(options: .diacriticInsensitive, locale: .current)
            .range(of: substring
                    .lowercased()
                    .folding(options: .diacriticInsensitive, locale: .current)) {
            let startPos = distance(from: startIndex, to: range.lowerBound)
            let endPos = distance(from: startIndex, to: range.upperBound)
            let firstSubstring = self[..<startPos]
            let secondSubstring = self[range]
            let thirdSubstring = self[endPos...]
            return "\(firstSubstring)[\(secondSubstring)]\(thirdSubstring)"
        } else {
            return ""
        }
    }
}

然而,在尝试时:

print("Curaçao".highlight(substring: "aca"))

库拉索

另一个例子是:

print("Curaçaoçao".highlight(substring: "acaoca"))

库拉索

是什么引起的?谢谢你的帮助

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-22 07:41:22

您可以简单地使用localizedStandardRange,它是不区分大小写的。顺便说一下,不需要将范围转换为整数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
localizedStandardRange(of:)

通过执行大小写和不敏感的、区域设置感知的搜索,查找并返回字符串中给定字符串的第一次出现的范围。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extension StringProtocol where Self: RangeReplaceableCollection {
    func highlight<S: StringProtocol>(substring: S) -> SubSequence? {
        guard let range = localizedStandardRange(of: substring) else { return nil }
        return self[..<range.lowerBound] + "[" + self[range] + "]" + self[range.upperBound...]
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print("Curaçao".highlight(substring: "aca") ?? "")
print("Curaçaoçao".highlight(substring: "acaoca") ?? "")

这个会打印出来

库拉索 库拉索

如果只想修复扩展的问题,只需将适当的选项caseInsensitivediacriticInsensitive传递给range方法,不要将范围转换为整数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func highlight(substring: String) -> String {
    if let range = range(of: substring, options: [.caseInsensitive, .diacriticInsensitive]) {
        let firstSubstring = self[..<range.lowerBound]
        let secondSubstring = self[range]
        let thirdSubstring = self[range.upperBound]
        return "\(firstSubstring)[\(secondSubstring)]\(thirdSubstring)"
    } else {
        return ""
    }
}

您的方法失败的原因是您在哪里搜索范围和计数不同字符串上的距离。

票数 3
EN

Stack Overflow用户

发布于 2021-02-22 07:51:13

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extension String {
    subscript(_ range: CountableRange<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
        let end = index(start, offsetBy: min(self.count - range.lowerBound, 
                                             range.upperBound - range.lowerBound))
        return String(self[start..<end])
    }

    subscript(_ range: CountablePartialRangeFrom<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
        return String(self[start...])
    }

    func highlight(substring: String) -> String {
        let stringWithoutCaseOrLetters = self.folding(options: .diacriticInsensitive, locale: .current)
        if let range = lowercased()
            .folding(options: .diacriticInsensitive, locale: .current)
            .range(of: substring
                    .lowercased()
                    .folding(options: .diacriticInsensitive, locale: .current)) {
            let startPos:Int = stringWithoutCaseOrLetters.distance(from: startIndex, to: range.lowerBound)
            let endPos:Int = stringWithoutCaseOrLetters.distance(from: startIndex, to: range.upperBound)
            let firstSubstring = self[0..<startPos]
            let secondSubstring = self[startPos..<endPos]
            let thirdSubstring = self[endPos...]
            return "\(firstSubstring)[\(secondSubstring)]\(thirdSubstring)"
        }
        return ""
    }
}

extension StringProtocol {
    func distance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func distance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}

extension Collection {
    func distance(to index: Index) -> Int { distance(from: startIndex, to: index) }
}

extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(to: self) }
}

let string = "Curaçao"
print(string[0..<string.count])
print(string.highlight(substring: "aca"))

print("Curaçaoçao".highlight(substring: "acaoca"))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66317623

复制
相关文章
比较字符串(忽略空格,忽略大小写)
总时间限制: 1000ms内存限制: 65536kB描述 判断两个由大小写字母和空格组成的字符串在忽略大小写,且忽略空格后是否相等。 输入两行,每行包含一个字符串。输出若两个字符串相等,输出YES,否则输出NO。样例输入 a A bb BB ccc CCC Aa BBbb CCCccc 样例输出 YES 源码如下: #include <iostream> using namespace std; bool compareTwoStringIgnoreCases(string a,string b); in
用户1631856
2018/04/12
3.2K0
16:忽略大小写的字符串比较
16:忽略大小写的字符串比较 总时间限制: 1000ms 内存限制: 65536kB描述 一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止。如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准(注意:如果某个字符串遇到'\0'而另一个字符串还未遇到'\0',则前者小于后者)。但在有些时候,我们比较字符串的大小时,希望忽略字母的大小,例如"Hello"和"hell
attack
2018/04/03
1.7K0
忽略大小写比较字符串大小
一般我们用 strcmpstrcmp 可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按 ASCII 码值大小比较),直到出现不同的字符或遇到 \0 为止。
莫浅子
2022/11/18
1.2K0
python 字符串比较忽略大小写的方法
A.正则表达式,使用IGNORECASE标志 >>> import re >>> m = re.search('multi', 'A mUltiCased string', re.IGNORECASE) >>> bool(m) True B.在比较前把2个字符串转换成同样大写,用upper()方法,或小写,lower() >>> s = 'A mUltiCased string'.lower() >>> s 'a multicased string' >>> s.find('multi') 2
py3study
2020/01/14
8.3K0
python 字符串搜索替换(忽略大小写)
re.IGNORECASE text = 'UPPER PYTHON, lower python, Mixed Python' re.findall('python', text, flags=re.IGNORECASE) ['PYTHON', 'python', 'Python'] re.sub('python', 'snake', text, flags=re.IGNORECASE) 'UPPER snake, lower snake, Mixed snake'
用户5760343
2022/01/10
1K0
Swift4 获取String子字符串
都说Swift2和Swift3不是同一门语言,但是我怎么觉得Swift4有时看着也像别人家的孩子。。。。 这里主要是更新下以前的写的Swift3的String相关知识:
韦弦zhy
2018/09/11
6270
Swift 字符串和字符
Swift 字符串通过 String 类型来表示,也可以表示为 Character 类型值的集合。
Swift社区
2021/11/26
7930
Swift基础 字符串和字符
翻译自:https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
郭顺发
2023/07/17
1920
Swift基础 字符串和字符
go 生成随机字符串和获得定长字符串
挑战A.I.,赢百万奖金......了解更多详情>>> 随机字符串 //RandomStr 随机生成字符串 func RandomStr(length int) string { str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" bytes := []byte(str) result := []byte{} r := rand.New(rand.NewSource(time.Now().UnixNano
solate
2019/07/19
1.8K0
ToStringBuilder如何忽略null和空字符串
日常开发中,经常用org.apache.commons.lang3.builder.ToStringBuilder工具类来记录日志,比如:
菩提树下的杨过
2022/05/09
1.1K0
Swift教程(三)--字符串和字符
字符串是一系列的字符,比如说 “hello, world”或者 “likeyou”。Swift 的字符串用 String类型来表示。 String的内容可以通过各种方法来访问到,包括作为 Character值的集合。
roc
2019/07/31
6070
获得定长字符串
        C#中的字符串是Unicode编码,length是Unicode的Char的个数。所以,假如一个字符串中中英文混杂,又想获得一个固定宽度的字符串,就比较麻烦。单纯转换成字节再截取难免会碰到半个汉字的问题。         下面实现了这样的功能,返回固定字节长度的字符串,如果发生截断,后面补充2个或者3个“.”,根据截断点的位置决定。 /// <summary>         /// 返回定长的字符串,如果发生截取,在后面补充两个或三个"."         /// Author:jetz
用户1075292
2018/01/23
7880
Swift3 获取String子字符串Substring简单扩展
Swift3更新后不兼容Swift2了,刚开始看Swift,发现好多方法都不能用了啊,那就只能自己摸索了,同时也在这与大家分享分享,正好让大家帮我指正。
韦弦zhy
2018/09/11
6700
Python 字符串的大小写(一)
文章链接: https://icodeq.com/2021/6a332b281b55/
Zkeq
2022/05/18
5770
Swift3.0 for 循环和遍历字符串
未经允许不得转载:RffanLAB|Rffan实验室 » Swift3.0 for 循环和遍历字符串
用户2353021
2020/05/09
9010
[译]Swift中的空字符串
Swift 一个特色就是有很多的语法糖,初学可能觉得hold不住,实际用的时候倒是挺便利。
小刀c
2022/08/16
9800
Python字符串的大小写(二)
文章链接: https://icodeq.com/2021/28d6866714c1/
Zkeq
2022/05/18
5960
字符串——459. 重复的子字符串
示例 1: 输入: s = “abab” 输出: true 解释: 可由子串 “ab” 重复两次构成。
向着百万年薪努力的小赵
2022/12/02
1.4K0
字符串中查找子串_cstring查找子字符串
假设要从主串 s = “goodgoogle” 中找到 t = “google” 子串。根据我们的思考逻辑,则有:
全栈程序员站长
2022/09/24
3K0
字符串中查找子串_cstring查找子字符串
Java 字符串大小写转化
str.toLowerCase() 将String转换为小写,如果字符串中没有应该被转换的字符,返回原字符串
桑鱼
2020/04/24
1.2K0
Java 字符串大小写转化

相似问题

Java字符串比较-忽略字母、重音和大小写

15

如何匹配忽略大小写和重音的字符串?

24

LINQ,忽略重音和大小写

73

搜索字符串,忽略重音

23

忽略重音的Java字符串搜索

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文