如何在Swift中从文本中提取主题标签字符串?我已经看到了一些答案,但是它们似乎对我需要的东西来说太复杂了,我真的不了解RegEx的工作原理吗?
例如
文字:“这是#东西,带有#随机##标签#123yay。”
我想要的是:“某物”,“随机”,“标签”,“ 123yay”。
谢谢!
答案 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:
答案 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()
结果:
礼貌:贾里德·戴维森在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()
答案 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
答案 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")