4

データベース プログラムでの出力用に、太字または斜体を示すためにマークを挿入した特定のテキストと、画像の代わりに使用するテキストがあります。例えば:

「%Important% ^All employees to the breakroom^」の最終出力は次のようになります。

重要 全従業員は休憩室へ

「%」記号と「^」記号で囲まれたテキストを検索するコードを記述しましたが、現在の問題は次のようなテキスト出力です。

%重要% ^全社員、休憩室へ^

文字列のフォーマットを保持しながら、これらの % と ^ を削除したいと思います。

これは、壊れるまで使用しているコードです。

func processText(inString string: String) -> NSAttributedString {

let pattern = ["(?<=\\^).*?(?=\\^)","(?<=\\%).*?(?=\\%)","\\^", "\\%"]
let italicsRegex = NSRegularExpression(pattern: pattern[0], options: .allZeros, error: nil)
let range = NSMakeRange(0, count(string))
let italicsMatches = italicsRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var attributedText = NSMutableAttributedString(string: string)

for match in italicsMatches! {
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 14.0)!, range: match.range)
}

let boldRegex = NSRegularExpression(pattern: pattern[1], options: .allZeros, error: nil)
let boldMatches = boldRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

for match in boldMatches!   {
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Bold", size: 14.0)!, range: match.range)
}

let removeItalicsMarksRegex = NSRegularExpression(pattern: pattern[2], options: .allZeros, error: nil)
let removeItalicsMarksMatches = removeItalicsMarksRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var numberOfLoops = 0
for match in removeItalicsMarksMatches! {

    attributedText.replaceCharactersInRange(match.range, withString: "")

}

return attributedText.copy() as! NSAttributedString
}

これは % 一致 (ただし最初の文字のみ) で機能し、^ 文字ですぐにクラッシュします。

これを解決するための助けやアドバイスをいただければ幸いです。ありがとう。

4

3 に答える 3

2

マーティン、

非常によく似たものを使用することになりましたが、正規表現を変更して ^ マークを含めることにしました。そうすることで、「replaceCharactersInRange」メソッドを使用して、含まれている属性付き部分文字列の最初と最後の文字を切り取ることができました。これは、属性付きの文字列から機能しているため、属性を台無しにしたり削除したりしないため、これまでの目的では少しうまく機能します。

今後の参考のために、正規表現とイタリック体を扱うコードの一部を添付しました (また、ありがとうございます!)。

func processText(inString string: String) -> NSAttributedString {

let pattern = ["\\^.*?\\^"] //Presented as an array here because in the full code there are a lot of patterns that are run.




let italicsRegex = NSRegularExpression(pattern: pattern[0], options: .allZeros, error: nil) 

//In addition to building the match for this first regular expression, I also gather build the regular expressions and gather matches for all other matching patterns on the initial string ("string") before I start doing any processing.

    let range = NSMakeRange(0, count(string.utf16))

let italicsMatches = italicsRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var attributedText = NSMutableAttributedString(string: string)

var charactersRemovedFromString = 0

for match in italicsMatches! {

    let newRange = NSMakeRange(match.range.location - charactersRemovedFromString, match.range.length) // Take the updated range for when this loop iterates, otherwise this crashes.
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 12.0)!, range: newRange)

    let rangeOfFirstCharacter = NSMakeRange(match.range.location - charactersRemovedFromString, 1)

    attributedText.replaceCharactersInRange(rangeOfFirstCharacter, withString: "")

    charactersRemovedFromString += 2

    let rangeOfLastCharacter = NSMakeRange(match.range.location + match.range.length - charactersRemovedFromString, 1)

    attributedText.replaceCharactersInRange(rangeOfLastCharacter, withString: "")
    }

return attributedText
}
于 2015-04-14T17:24:58.263 に答える
1

これは可能な解決策です。本質的に、 複数のインスタンスをキャッチする方法の翻訳です NSString で特別に指定された **文字** で、それらの間を太字にしますか? Objective-C から Swift まで。

アイデアは、1 つのループで属性を追加し、区切り文字削除することです。このshift 変数は、最初の区切り文字が削除された後、一致する範囲を調整するために必要です。

簡単にするために、「^...^」処理のみを示します。

func processText(inString string: String) -> NSAttributedString {

    let pattern = "(\\^)(.*?)(\\^)"

    let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)!
    var shift = 0 // number of characters removed so far
    let attributedText = NSMutableAttributedString(string: string)
    regex.enumerateMatchesInString(string, options: nil, range: NSMakeRange(0, count(string.utf16))) {
        (result, _, _) -> Void in
        var r1 = result.rangeAtIndex(1) // Location of the leading delimiter
        var r2 = result.rangeAtIndex(2) // Location of the string between the delimiters
        var r3 = result.rangeAtIndex(3) // Location of the trailing delimiter
        // Adjust locations according to the string modifications:
        r1.location -= shift
        r2.location -= shift
        r3.location -= shift
        // Set attribute for string between delimiters:
        attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 14.0)!, range: r2)
        // Remove leading and trailing delimiters:
        attributedText.mutableString.deleteCharactersInRange(r3)
        attributedText.mutableString.deleteCharactersInRange(r1)
        // Update offset:
        shift += r1.length + r3.length
    }

    return attributedText.copy() as! NSAttributedString
}

enumerateMatchesInString()がかかることに注意してくださいNSRange。したがって、Swift の文字数ではなく、UTF-16 の文字数を計算する必要があります。

例:

let text = "aaa ^bbb^ eee"
let attrText = processText(inString: text)
println(attrText)

出力:

ああ{
}bb{
    NSFont = " font-family: \"Helvetica-Oblique\"; font-weight: normal; font-style: italic; font-size: 14.00pt";
}ええ{
}
于 2015-04-13T10:03:21.253 に答える