Swift - 将属性字符串添加到括号中的项目

时间:2017-04-19 20:43:45

标签: regex swift string

我试图通过一组定义向一个视图显示文本,并且在该文本/字符串有括号的情况下,我想以不同的方式显示该括号元素 - 让我们说粗体与非粗体。

  

" 此字符串a "

     

" 此字符串b (括号)" - 括号显示在较低位置   重量字体

现在我意识到解决方案是通过将正则表达式\(\w*\) - 与属性字符串结合起来找到的,但我还没有能够将它有意义地结合起来。

这是我打印单词

的功能
func setWord(_ index:Int) {
    if (index < 0) { return }
    let word:[String:AnyObject] = self.definitions[index]
    if let wordLabelText = word[self.store.sourceLanguage.lowercased()] as? String {
        self.wordLabel.attributedText = NSMutableAttributedString(string: wordLabelText, attributes: [NSKernAttributeName: 1.0])
    }
    print(word)
    self.definitionView.word = word
}

我到目前为止所做的是为属性字符串输出添加了更多定义,但后来我不知道如何继续:

func setWord(_ index:Int) {
    if (index < 0) { return }
    let font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
    let fontSize = font.pointSize * 3
    let plainFont = UIFont(name: "X-BoldItalic", size: fontSize)
    let boldFont = UIFont(name: "X-Italic", size: fontSize)
    let word:[String:AnyObject] = self.definitions[index]
    if let wordLabelText = word[self.store.sourceLanguage.lowercased()] as? String {
        self.wordLabel.attributedText = NSMutableAttributedString(string: wordLabelText, attributes: [NSKernAttributeName: 1.0, NSFontAttributeName: boldFont])

在这里,我需要遍历寻找(元素)的单词,但我不确定如何做到这一点并正确地返回单词。我在正确的道路上吗?谢谢你们:)

1 个答案:

答案 0 :(得分:1)

Objective-C中的解决方案,其解释逻辑应该可以在Swift中轻松翻译。

NSDictionary *defaultAttributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:15]};
NSDictionary *otherAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:12]};

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\(.*?\\)" options:0 error:nil];
NSString *initialString = @"This string a (has parenthesis), This string b (has parenthesis too), This string C hasn't.";

NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:initialString attributes:defaultAttributes];
NSLog(@"Attr: %@", attr);
NSArray *allMatches = [regex matchesInString:[attr string] options:0 range:NSMakeRange(0, [attr length])];
for (NSTextCheckingResult *aResult in allMatches)
{
    [attr addAttributes:otherAttributes range:[aResult range]];
}
NSLog(@"Attr: %@", attr);

日志:

$> Attr: This string a (has parenthesis), This string b (has parenthesis too), This string C hasn't.{
    NSFont = "<UICTFont: 0x14663df0> font-family: \".SFUIText-Semibold\"; font-weight: bold; font-style: normal; font-size: 15.00pt";
}
$> Attr: This string a {
    NSFont = "<UICTFont: 0x14663df0> font-family: \".SFUIText-Semibold\"; font-weight: bold; font-style: normal; font-size: 15.00pt";
}(has parenthesis){
    NSFont = "<UICTFont: 0x14666260> font-family: \".SFUIText\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
}, This string b {
    NSFont = "<UICTFont: 0x14663df0> font-family: \".SFUIText-Semibold\"; font-weight: bold; font-style: normal; font-size: 15.00pt";
}(has parenthesis too){
    NSFont = "<UICTFont: 0x14666260> font-family: \".SFUIText\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
}, This string C hasn't.{
    NSFont = "<UICTFont: 0x14663df0> font-family: \".SFUIText-Semibold\"; font-weight: bold; font-style: normal; font-size: 15.00pt";
}

这是什么想法:
创建一个带有“默认”属性的NSMutableAttributedString(在我们的例子中是带有“大尺寸”的粗体字体) 然后创建一个NSRegularExpression并查找所有出现的内容 您将在该发生范围添加属性(在我们的示例中为小字体和普通字体)。

在我们的例子中,它很简单,因为在特定范围内每种类型最多只能有一个属性,NSFontAttributeName属性将替换为该范围。

如果您添加了更多属性,并希望将其删除,则可能需要拨打addAttributes:range:,而不是replaceCharactersInRange:withAttributedString:

NSAttributedString *replacement = [[NSAttributedString alloc] initWithString:[[attr string] substringWithRange:[aResult range]]
                                                                  attributes:otherAttributes];
[attr replaceCharactersInRange:[aResult range] withAttributedString:replacement];

编辑: Swift 3版

Nota Bene:我显然不是Swift开发人员,这段代码似乎有用,但很明显,我“写”Swift就像我写Objective-C一样,很多事情因为我不喜欢每天使用它们并且没有读错了文档(比如转换/演员/显式类/类,“as”,“!”,“?”等),但它可能是一个为你而开始。 如果您是Swift开发人员并发现问题,请随时评论该帖子并建议您进行修改。如果你因为遇到同样的问题就在这里,如果我的伪代码中还有更多要解决的Swifty内容,请不要忘记阅读评论。

let defaultAttributes:[String:Any] = [NSFontAttributeName:UIFont.boldSystemFont(ofSize:15)];
let otherAttributes:[String:Any] = [NSFontAttributeName:UIFont.systemFont(ofSize:12)];


do {
    let regex = try NSRegularExpression.init(pattern: "\\(.*?\\)", options: [])
    let initialString:String = "This string a (has parenthesis), This string b (has parenthesis too), This string C hasn't."
    let attr = NSMutableAttributedString.init(string: initialString, attributes: defaultAttributes)
    print("Attr\(attr)");
    let allMatches:[NSTextCheckingResult] = regex.matches(in: attr.string, options:[], range: NSRange(location: 0, length: attr.string.characters.count))
    for aResult in allMatches
    {
        let occurrence = (attr.string as NSString).substring(with: aResult.range)
        let replacement = NSAttributedString.init(string: occurrence , attributes: otherAttributes)
        attr.replaceCharacters(in: aResult.range, with: replacement)
    //attr.addAttributes(otherAttributes, range: aResult.range)
    }
    print("Attr\(attr)");
} catch let regexError {
    print(regexError)
}