字符串-用另一个NSAttributedString替换NSAttributedString的子字符串

我想用另一个NSAttributedString替换NSAttributedString的子字符串(例如stringByReplacingOccurrencesOfString:withString:)。

我正在寻找NSAttributedStringstringByReplacingOccurrencesOfString:withString:stringByReplacingOccurrencesOfString:withString:的等效方法。

9个解决方案
77 votes
  1. 将您的属性字符串转换为replaceOccurrencesOfString:withString:options:range:的实例。

  2. 可变属性字符串具有replaceOccurrencesOfString:withString:options:range:属性。 根据文档:

    “接收方跟踪对此字符串的更改,并使其属性映射保持最新。”

    因此,您可以使用生成的可变字符串执行replaceOccurrencesOfString:withString:options:range:的替换。

Ole Begemann answered 2020-01-13T07:25:51Z
19 votes

以下是更改NSMutableAttributedString的字符串的同时保留其属性的方法:

迅速:

// first we create a mutable copy of attributed text 
let originalAttributedText = nameLabel.attributedText?.mutableCopy() as! NSMutableAttributedString

// then we replace text so easily
let newAttributedText = originalAttributedText.mutableString.setString("new text to replace")

目标C:

NSMutableAttributedString *newAttrStr = [attribtedTxt.mutableString setString:@"new string"];
Hashem Aboonajmi answered 2020-01-13T07:26:20Z
18 votes

就我而言,以下方法是唯一的(在iOS9上经过测试):

NSAttributedString *attributedString = ...;
NSAttributedString *anotherAttributedString = ...; //the string which will replace

while ([attributedString.mutableString containsString:@"replace"]) {
        NSRange range = [attributedString.mutableString rangeOfString:@"replace"];
        [attributedString replaceCharactersInRange:range  withAttributedString:anotherAttributedString];
    }

当然,找到另一种更好的方法会很高兴。

Darius Miliauskas answered 2020-01-13T07:26:44Z
9 votes

使用Swift 4和iOS 11,您可以使用以下两种方法之一来解决问题。


#1。 使用replaceOccurrences(of:with:options:range:) NSMutableAttributedString方法

replaceOccurrences(of:with:options:range:)具有称为replaceOccurrences(of:with:options:range:)的方法。NSMutableAttributedString具有以下声明:

将给定范围内的字符和属性替换为给定属性字符串的字符和属性。

func replaceCharacters(in range: NSRange, with attrString: NSAttributedString)

下面的Playground代码显示了如何使用replaceOccurrences(of:with:options:range:)NSMutableAttributedString实例的子字符串替换为新的NSMutableAttributedString实例:

import UIKit

// Set initial attributed string
let initialString = "This is the initial string"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let mutableAttributedString = NSMutableAttributedString(string: initialString, attributes: attributes)

// Set new attributed string
let newString = "new"
let newAttributes = [NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue]
let newAttributedString = NSMutableAttributedString(string: newString, attributes: newAttributes)

// Get range of text to replace
guard let range = mutableAttributedString.string.range(of: "initial") else { exit(0) }
let nsRange = NSRange(range, in: mutableAttributedString.string)

// Replace content in range with the new content
mutableAttributedString.replaceCharacters(in: nsRange, with: newAttributedString)

#2。 使用replaceOccurrences(of:with:options:range:) NSMutableAttributedString方法

replaceOccurrences(of:with:options:range:)具有称为replaceOccurrences(of:with:options:range:)的方法。NSMutableAttributedString具有以下声明:

将给定范围内的所有给定字符串替换为另一个给定字符串,并返回替换次数。

func replaceOccurrences(of target: String, with replacement: String, options: NSString.CompareOptions = [], range searchRange: NSRange) -> Int

下面的Playground代码显示了如何使用replaceOccurrences(of:with:options:range:)NSMutableAttributedString实例的子字符串替换为新的NSMutableAttributedString实例:

import UIKit

// Set initial attributed string
let initialString = "This is the initial string"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let mutableAttributedString = NSMutableAttributedString(string: initialString, attributes: attributes)

// Set new string
let newString = "new"

// Replace replaceable content in mutableAttributedString with new content
let totalRange = NSRange(location: 0, length: mutableAttributedString.string.count)
_ = mutableAttributedString.mutableString.replaceOccurrences(of: "initial", with: newString, options: [], range: totalRange)

// Get range of text that requires new attributes
guard let range = mutableAttributedString.string.range(of: newString) else { exit(0) }
let nsRange = NSRange(range, in: mutableAttributedString.string)

// Apply new attributes to the text matching the range
let newAttributes = [NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue]
mutableAttributedString.setAttributes(newAttributes, range: nsRange)
Imanou Petit answered 2020-01-13T07:27:41Z
6 votes

我必须在<b>标签中将文本加粗,这是我所做的:

- (NSAttributedString *)boldString:(NSString *)string {
    UIFont *boldFont = [UIFont boldSystemFontOfSize:14];
    NSMutableAttributedString *attributedDescription = [[NSMutableAttributedString alloc] initWithString:string];

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@".*?<b>(.*?)<\\/b>.*?" options:NSRegularExpressionCaseInsensitive error:NULL];
    NSArray *myArray = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)] ;
    for (NSTextCheckingResult *match in myArray) {
        NSRange matchRange = [match rangeAtIndex:1];
        [attributedDescription addAttribute:NSFontAttributeName value:boldFont range:matchRange];
    }
    while ([attributedDescription.string containsString:@"<b>"] || [attributedDescription.string containsString:@"</b>"]) {
        NSRange rangeOfTag = [attributedDescription.string rangeOfString:@"<b>"];
        [attributedDescription replaceCharactersInRange:rangeOfTag withString:@""];
        rangeOfTag = [attributedDescription.string rangeOfString:@"</b>"];
        [attributedDescription replaceCharactersInRange:rangeOfTag withString:@""];
    }
    return attributedDescription;
}
trickster77777 answered 2020-01-13T07:28:01Z
6 votes

斯威夫特4:更新了sunkas对Swift 4的出色解决方案,并包含在“扩展名”中。 只需将其剪辑到您的ViewController中(在类外部)并使用它即可。

extension NSAttributedString {
    func stringWithString(stringToReplace: String, replacedWithString newStringPart: String) -> NSMutableAttributedString
    {
        let mutableAttributedString = mutableCopy() as! NSMutableAttributedString
        let mutableString = mutableAttributedString.mutableString
        while mutableString.contains(stringToReplace) {
            let rangeOfStringToBeReplaced = mutableString.range(of: stringToReplace)
            mutableAttributedString.replaceCharacters(in: rangeOfStringToBeReplaced, with: newStringPart)
        }
        return mutableAttributedString
    }
}
gundrabur answered 2020-01-13T07:28:21Z
4 votes
NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:@"I am a boy."];
[result addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, [result length])];

NSMutableAttributedString *replace = [[NSMutableAttributedString alloc] initWithString:@"a"];
[replace addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, [replace length])];

[result replaceCharactersInRange:NSMakeRange(5, [replace length]) withAttributedString:replace];
Chan Kai Long answered 2020-01-13T07:28:37Z
2 votes

我发现所有其他答案均无效。 这是我如何替换类别扩展中的NSAttributed字符串的内容:

func stringWithString(stringToReplace:String, replacedWithString newStringPart:String) -> NSMutableAttributedString
{
    let mutableAttributedString = mutableCopy() as! NSMutableAttributedString
    let mutableString = mutableAttributedString.mutableString

    while mutableString.containsString(stringToReplace) {
        let rangeOfStringToBeReplaced = mutableString.rangeOfString(stringToReplace)
        mutableAttributedString.replaceCharactersInRange(rangeOfStringToBeReplaced, withString: newStringPart)
    }
    return mutableAttributedString
}
Sunkas answered 2020-01-13T07:28:57Z
2 votes

我有一个特定的要求,并固定如下。 这可能会帮助某人。

要求:在情节提要中,富文本直接添加到UITextView的属性中,其中包含单词“ App Version:1.0”。 现在,我必须通过从信息plist中读取版本号来对其进行动态化。

解:从情节提要中删除了版本号1.0,仅保留了“应用程序版本:”并添加了以下代码。

NSAttributedString *attribute = self.firsttextView.attributedText;
NSMutableAttributedString *mutableAttri = [[NSMutableAttributedString alloc] initWithAttributedString:attribute];
NSString *appVersionText = @"App Version:";
if ([[mutableAttri mutableString] containsString:appVersionText]) {
    NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];
    NSString* version = [infoDict objectForKey:@"CFBundleShortVersionString"];
    NSString *newappversion = [NSString stringWithFormat:@"%@ %@",appVersionText,version] ;
    [[mutableAttri mutableString] replaceOccurrencesOfString:appVersionText withString:newappversion options:NSCaseInsensitiveSearch range:NSMakeRange(0, mutableAttri.length)];
    self.firsttextView.attributedText = mutableAttri;
}

做完了! 更新/修改了attributedText。

Suresh Durishetti answered 2020-01-13T07:29:30Z
translate from https://stackoverflow.com:/questions/8231240/replace-substring-of-nsattributedstring-with-another-nsattributedstring