快速从文本中提取主题标签字符串

时间:2018-07-24 08:56:10

标签: swift

如何在Swift中从文本中提取主题标签字符串?我已经看到了一些答案,但是它们似乎对我需要的东西来说太复杂了,我真的不了解RegEx的工作原理吗?

例如

文字:“这是#东西,带有#随机##标签#123yay。”

我想要的是:“某物”,“随机”,“标签”,“ 123yay”。

谢谢!

10 个答案:

答案 0 :(得分:3)

here is the helper method to convert your string into hash detection string

this extension find the # words from sting also including arabic words.

extension String {
    func findMentionText() -> [String] {
        var arr_hasStrings:[String] = []
        let regex = try? NSRegularExpression(pattern: "(#[a-zA-Z0-9_\\p{Arabic}\\p{N}]*)", options: [])
        if let matches = regex?.matches(in: self, options:[], range:NSMakeRange(0, self.count)) {
            for match in matches {
                arr_hasStrings.append(NSString(string: self).substring(with: NSRange(location:match.range.location, length: match.range.length )))
            }
        }
        return arr_hasStrings
    }
}

And below method converts your string into Reach colorful hash string.

func convert(_ hashElements:[String], string: String) -> NSAttributedString {

    let hasAttribute = [NSAttributedStringKey.foregroundColor: UIColor.orange]

    let normalAttribute = [NSAttributedStringKey.foregroundColor: UIColor.black]

    let mainAttributedString = NSMutableAttributedString(string: string, attributes: normalAttribute)

    let txtViewReviewText = string as NSString

    hashElements.forEach { if string.contains($0) {
        mainAttributedString.addAttributes(hasAttribute, range: txtViewReviewText.range(of: $0))
        }
    }
    return mainAttributedString
}

i.e

let text = "#Jaydeep #Viral you have to come for party"

let hashString = convert(text.findMentionText(), string: text)

Output:

enter image description here

答案 1 :(得分:1)

首先,这在TextView中效果最好。因此,可以根据需要在视图内部设置一个,但请确保ViewController具有UITextViewDelegate并将textView委托给该视图控制器。 我也使用一些预填充的信息来执行此操作,但是相同的概念适用于从数据库中提取数据,而不是提取数据。

这是我们设置ViewController的方式:

class ViewController: UIViewController, UITextViewDelegate {
    var string = "Hello, my name is @Jared & #Jared and I like to move it."
    @IBOutlet weak var textView: UITextView!
    override func viewDidLoad() {
        super.viewDidLoad()
        textView.text = string
        textView.delegate = self
    }

这部分我们要完成的总体任务只是将textView中的所有单词分割开。它比您想象的要简单: 首先,让我们创建扩展程序:

现在将其添加到您的ViewController中:

extension UITextView {
    func resolveTags(){
        let nsText:NSString = self.text as NSString
        let words:[String] = nsText.components(separatedBy: " ")

        let attrs = [
            NSAttributedStringKey.font : UIFont.init(name: "HelveticaNeue", size: 13),
            NSAttributedStringKey.foregroundColor : UIColor.black

        ]

        let attrString = NSMutableAttributedString(string: nsText as String, attributes:attrs)

        for word in words {
            if word.hasPrefix("#") {
                let matchRange:NSRange = nsText.range(of: word as String)
                var stringifiedWord:String = word as String
                stringifiedWord = String(stringifiedWord.dropFirst())
                attrString.addAttribute(NSAttributedStringKey.link, value: "hash:\(stringifiedWord)", range: matchRange)
                attrString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue , range: matchRange)
          }
        }
        self.attributedText = attrString
    }
}

让我们使用这个东西!

一切都归结为这一点。我们已经启用了此功能,现在如何使用它?

容易

viewDidLoad函数内部或设置textView文本的任何位置,只需调用:

textView.resolveTags()

结果:

Result

礼貌:贾里德·戴维森在Twitter上

答案 2 :(得分:1)

extension String
{
    func hashtags() -> [String]
    {
        if let regex = try? NSRegularExpression(pattern: "#[a-z0-9]+", options: .caseInsensitive)
        {
            let string = self as NSString

            return regex.matches(in: self, options: [], range: NSRange(location: 0, length: string.length)).map {
                string.substring(with: $0.range).replacingOccurrences(of: "#", with: "").lowercased()
            }
        }

        return []
    }
}

然后,获取主题标签数组

yourstring.hashtags()

Here is the source

答案 3 :(得分:1)

 let str =  "This is #something with a lot of #random #hashtags #123yay."
 let words = str.components(separatedBy: " ")
 var hashTags = [String]()
 for word in words{
     if word.hasPrefix("#"){
         let hashtag = word.dropFirst()
         hashTags.append(String(hashtag))
     }
 }
 print("Hashtags :: ", hashTags)

答案 4 :(得分:0)

You can also use third party Activelabel . this is simple to use and also support Hashtags (#), Mentions (@), URLs (http://) and custom regex patterns

https://github.com/optonaut/ActiveLabel.swift

答案 5 :(得分:0)

我只是将@JayDeep的答案更改为更快捷的样式。

extension String {
  var tags: [String] {
    let regex = try? NSRegularExpression(pattern: "(#[a-zA-Z0-9_\\p{Arabic}\\p{N}]*)", options: [])
    let nsRange: NSRange = .init(location: 0, length: self.count)
    guard let matches = regex?.matches(in: self, options: NSRegularExpression.MatchingOptions(), range: nsRange)
      else { return [] }
    return matches
      .map { match in
        let startIndex = self.index(self.startIndex, offsetBy: match.range.location)
        let endIndex = self.index(startIndex, offsetBy: match.range.length)
        let range = startIndex ..< endIndex
        return String(self[range])
      }
  }
}

答案 6 :(得分:0)

我的干净解决方案:我们将 PrefixesDetected 返回到视图。视图将按他的意愿对其进行格式化。 (因此,我们将在viewModel中执行yourString.resolvePrefixes()),我们将对其进行测试。

struct PrefixesDetected {
   let text: String
   let prefix: String?
}


extension String {
    func resolvePrefixes(_ prefixes: [String] = ["#", "@"]) -> [PrefixesDetected] {

        let words = self.components(separatedBy: " ")

        return words.map { word -> PrefixesDetected in
            PrefixesDetected(text: word,
                             prefix: word.hasPrefix(prefixes: prefixes))
        }
    }

    func hasPrefix(prefixes: [String]) -> String? {
        for prefix in prefixes {
            if hasPrefix(prefix) {
                return prefix
            }
        }
        return nil
    }
}

然后在视图中,我们可以设置其格式,例如:(在这种情况下,我们希望它们都使用相同的颜色,但是您可以通过这种方式赋予它们不同的行为)

这里我使用reduce,但这只是为了显示一个示例,您可以根据需要设置其格式! :)

titleDetectedPrefixes.reduce(NSAttributedString(), { result, prefixDectedWord in

        let wordColor: UIColor = prefixDectedWord.prefix != nil ? .highlightTextMain : .mainText
        let attributedWord = NSAttributedString(string: prefixDectedWord.text)

        { Add desired attributes }
    })

答案 7 :(得分:0)

对于使用swiftUI的用户,可以使用“ +”运算符来实现 所以最终的解决方案看起来像这样

static func tagHighlighter(description : String , previousText : Text = Text("") , tag : String = "#") -> Text {


        var t : Text = Text("")

        let words : [String] = description.components(separatedBy: " ")

        for  word in words {

            if !word.isEmpty {

                let tag = word[word.startIndex]

                if tag == "@" {

                    t = t + Text("\(word) ").foregroundColor(Color("tag_color"))

                } else if tag == "#" {

                    t = t + Text("\(word) ").foregroundColor(Color("tag_color"))

                } else {
                    t = t + Text("\(word) ")
                }

            }

        }

        return t
    }

答案 8 :(得分:0)

这就是我的做法

    private func getHashTags(from caption: String) -> [String] {
    var words: [String] = []
    let texts = caption.components(separatedBy: " ")
    for text in texts.filter({ $0.hasPrefix("#") }) {
        if text.count > 1 {
            let subString = String(text.suffix(text.count - 1))
            words.append(subString.lowercased())
        }
    }
    return words
}

答案 9 :(得分:0)

将此扩展复制粘贴到您的班级:

extension UITextView{
func insertTextWithHashtags(text textString: String){

    let nsTextString: NSString = textString as NSString
    
    let simpleTextAttributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.foregroundColor : UIColor(named: "Black Color")!, NSAttributedString.Key.font : UIFont(name: "Inter-Regular", size: 16.0)!]
    let attributedString = NSMutableAttributedString(string: textString, attributes: simpleTextAttributes)
    
    var word = ""
    
    for text in textString+" "{ //+" " is for loop to run one extra time to complete hashtag
        
        if text == "#" || text == "\n" || text == " "{
            if word.hasPrefix("#"){
                let range = nsTextString.range(of: word)
                let link = [NSAttributedString.Key.link : word]
                attributedString.addAttributes(link, range: range)
                
                if text == "#"{
                    word = "#"
                }else{
                    word = ""
                }
            }else{
                if text == "#"{
                    word = "#"
                }
            }
        }else{
            if word.hasPrefix("#"){
                word.append(text)
            }
        }
    }

    //For for applying attributes to hashtag
    let linkAttributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.foregroundColor : UIColor(named: "Primary Color")!]
    self.linkTextAttributes = linkAttributes
    
    self.attributedText = attributedString
}

}

然后像这样调用它:

postTextView.insertTextWithHashtags(text: "#Hello#Hey #Space")

enter image description here