NSRegularExpression with arithmetic

I would like to resize the font in the HTML line so that I am half its size.

eg.

<div style="font-family:'Arial';font-size:43px;color:#ffffff;"> 

Will be

 <div style="font-family:'Arial';font-size:21.5px;color:#ffffff;"> 

and

 <div style="font-size:12px;"> 

Will be

 <div style="font-size:6px;"> 

How to do it with NSRegularExpression ?

Please note that 12, 6 and 43 and 21.5 are only examples. I need a regex as it should be a general solution for different font sizes

+4
source share
4 answers

I am a little reluctant to give an answer using regular expressions, because it has been repeatedly stated that parsing HTML with a regular expression is considered harmful, impossible, dangerous to your mind, etc. And all this is correct, it is not my intention to demand something else.

But even after all these warnings, the OP explicitly asked for a regex solution, so I'm going to share this code. It can be, at least, useful as an example, how to change a line by going over all regular expression matches.

 NSString *htmlString = @"<div style=\"font-family:'Arial';font-size:43px;color:#ffffff;\">\n" @"<div style=\"font-size:12px;\">\n"; NSRegularExpression *regex; regex = [NSRegularExpression regularExpressionWithPattern:@"font-size:([0-9]+)px;" options:0 error:NULL]; NSMutableString *modifiedHtmlString = [htmlString mutableCopy]; __block int offset = 0; [regex enumerateMatchesInString:htmlString options:0 range:NSMakeRange(0, [htmlString length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { // range = location of the regex capture group "([0-9]+)" in htmlString: NSRange range = [result rangeAtIndex:1]; // Adjust location for modifiedHtmlString: range.location += offset; // Get old point size: NSString *oldPointSize = [modifiedHtmlString substringWithRange:range]; // Compute new point size: NSString *newPointSize = [NSString stringWithFormat:@"%.1f", [oldPointSize floatValue]/2]; // Replace point size in modifiedHtmlString: [modifiedHtmlString replaceCharactersInRange:range withString:newPointSize]; // Update offset: offset += [newPointSize length] - [oldPointSize length]; } ]; NSLog(@"%@", modifiedHtmlString); 

Output:

 <div style="font-family:'Arial';font-size:21.5px;color:#ffffff;"> <div style="font-size:6.0px;"> 
+3
source

Use a real HTML parser to keep your sanity. The XML parser for this is incredibly fragile. There are a dozen different perfectly valid HTML syntax options that violate the NSAddict expression.

I suggest reading the top voted answer on this question, as it applies equally to HTML, as well as to XHTML or XML.

Open RegEx tags except XHTML tags contained offline

Please note that iOS / OS X system frameworks include XML / XML parsing capabilities. Use them.

+4
source

You can do it with NSString , it's pretty simple.

 [string stringByReplacingOccurrencesOfString:@"font-size:12px;" withString:@"font-size:6px;"]; 

Copy this function

 - (NSString *)setFontSize:(int)fontSize inHTMLString:(NSString *)htmlString { NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"font-size:[0-9]+px;" options:NSRegularExpressionCaseInsensitive error:nil]; NSString *newString = [regex stringByReplacingMatchesInString:htmlString options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, htmlString.length) withTemplate:[NSString stringWithFormat:@"font-size:%dpx;", fontSize]]; return newString; } 
+3
source

I would use DTCoreText for this. It parses this HTML for you and creates a related string. Then you can customize the font to your liking. Finally, you can either draw an attributed string using DTCoreText, or convert it back to HTML.

If you insist on HTML, I can suggest DTHTMLParser, which is a SAX-based HTML parser based on libxml2. It can parse any HTML. Although you still have to share CSS, which is not as simple as you think, even with RegEx. I have a category in NSString that breaks down the parameters so that you can restore the style with the changed values.

Having said that, you probably took the best advantage of my first recommendation.

+1
source

All Articles