我有一些纯Html字符串,其中一些有标题标签<b>Title</b>
。
facilities: "<b>Facilities</b><br/>24-hour security, Barbecue area, Car park, Clubhouse, Function room, Gym, Outdoor swimming pool, Playground, Swimming pool<br/><br/><b>Rooms</b><br/>Dining room, Ensuites, Living room, Maid\'s room, Utility room<br/><br/><b>Outdoor</b><br/>Balcony<br/><br/><b>View</b><br/>City, Open<br/><br/><b>Direction</b><br/>South East"
所以我使用NSRegularExpression
模式从字符串中提取标题并存储在字符串数组中。然后,我将这些标题粗体(归因于字符串)和显示。所以这就是我这样做的方式:
var titlesArray = [String]()
let regex = try! NSRegularExpression(pattern: "<b>(.*?)</b>", options: [])
let basicDescription = facilities as NSString
regex.enumerateMatchesInString(facilities, options: [], range: NSMakeRange(0, facilities.characters.count)) { result, flags, stop in
if let range = result?.rangeAtIndex(1) {
titlesArray.append(basicDescription.substringWithRange(range))
}
}
let convertedDescription = facilities.html2String as NSString
let attributedString = NSMutableAttributedString(string: convertedDescription as String, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(14.0)])
let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15.0)]
if titlesArray.count > 0 {
for i in 0..<titlesArray.count {
attributedString.addAttributes(boldFontAttribute, range: convertedDescription.rangeOfString(titlesArray[i]))
}
}
所以,一切都很好。但问题是,有时我会收到带有重复单词的Html标记字符串,其中一个是带有标题标签的标题,另一个只是一个简单的单词,我不需要加粗。但是这个函数会查找那个单词并在for循环中加粗它,并忽略简单单词后面的真实标题。
这就是我得到的:
所以在这里,我怎么能忽略第一个“户外”和大胆的第二个我想要的。谢谢你的帮助。
答案 0 :(得分:1)
在Objective-C中,不应该在Swift中翻译太难(因为看起来你已经知道了一些方法)。
使用attr1
呈现 init(data:, options:, documentAttributes:)
。我没有添加任何其他效果(例如粗体/普通,颜色的首选大小,你只需要枚举它并更改效果)
使用正则表达式,attr2
更像是您想要的方式。它只是没有考虑所有标签,只是粗体,我几乎没有编写新行(<br/>
到\n
)的替代品。但这可能是有用的东西。我没有对你的正则表达式做更多的测试(while循环可能会被卡住?)
NSString *str = @"<b>Facilities</b><br/>24-hour security, Barbecue area, Car park, Clubhouse, Function room, Gym, Outdoor swimming pool, Playground, Swimming pool<br/><br/><b>Rooms</b><br/>Dining room, Ensuites, Living room, Maid\'s room, Utility room<br/><br/><b>Outdoor</b><br/>Balcony<br/><br/><b>View</b><br/>City, Open<br/><br/><b>Direction</b><br/>South East";
NSError *errorAttr1 = nil;
NSAttributedString *attr1 = [[NSAttributedString alloc] initWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:&errorAttr1];
if (errorAttr1)
{
NSLog(@"Error AttributedStr Conversion with initWithData:options:documentsAttributes:error: %@", errorAttr1);
}
else
{
NSLog(@"attr1: %@", attr1);
[_tv1 setAttributedText:attr1];
}
str = [str stringByReplacingOccurrencesOfString:@"<br/>" withString:@"\n"];
NSError *errorRegex = nil;
NSString *openingTag = @"<b>";
NSString *closingTag = @"</b>";
NSString *pattern = [NSString stringWithFormat:@"%@(.*?)%@", openingTag, closingTag];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&errorRegex];
if (errorRegex)
{
NSLog(@"Error regex: %@", errorRegex);
return;
}
NSDictionary *boldAttributes = @{NSForegroundColorAttributeName:[UIColor darkGrayColor],
NSFontAttributeName:[UIFont boldSystemFontOfSize:15]};
NSDictionary *normalAttributes = @{NSForegroundColorAttributeName:[UIColor darkGrayColor],
NSFontAttributeName:[UIFont systemFontOfSize:14]};
NSMutableAttributedString *attr2 = [[NSMutableAttributedString alloc] initWithString:str attributes:normalAttributes]; //Add the initial attributes there
//Now we'll add the specific attribues
NSTextCheckingResult *match = [regex firstMatchInString:[attr2 string] options:0 range:NSMakeRange(0, [attr2 length])];
while (match)
{
NSRange range = [match range];
NSString *foundStr = [[attr2 string] substringWithRange:range];
NSAttributedString *temp = [[NSAttributedString alloc] initWithString:[foundStr substringWithRange:NSMakeRange([openingTag length], [foundStr length]-[openingTag length]-[closingTag length])] attributes:boldAttributes];
[attr2 replaceCharactersInRange:range withAttributedString:temp];
match = [regex firstMatchInString:[attr2 string] options:0 range:NSMakeRange(0, [attr2 length])];
}
NSLog(@"attr2: %@", attr2);
[_tv2 setAttributedText:attr2];
_tv1
和_tv2
是两个UITextView
(IBOulet
)。
它呈现:( _tv1
是顶部的,_tv2
是第二个。)
答案 1 :(得分:0)
我不知道你究竟想做什么,但确实考虑使用initializer that takes HTML?
Playgrounds的示例代码是:
if let url = Bundle.main.url(forResource: "file", withExtension: "html") {
do {
let data = try Data(contentsOf: url)
let attributedString = try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
let labelRect = CGRect(x: 0, y: 0, width: 500, height: 250)
let label = UILabel(frame: labelRect)
label.numberOfLines = 2
label.attributedText = attributedString
} catch {
print(error.localizedDescription)
}
}
使用此HTML:
<style>
body {
font-size: 20;
font-family: sans-serif;
}
</style>
<p><b>Hello</b> world</p>
<p>Good morning!</p>
输出如下: