iOS 字符串常用操作总结
来源:互联网 发布:安卓一键安装linux 编辑:程序博客网 时间:2024/05/18 22:50
搜索
在一个字符串中搜索子字符串
最灵活的方法
- (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)searchRange locale:(NSLocale *)locale
格式化字符串
3个方法
-initWithFormat:
-initWithFormat:arguments:
+stringWithFormat:
替换字符串
NSMutableString的四个方法
-deleteCharactersInRange:
-insertString:atIndex:
-replaceCharactersInRange:withString:
-replaceOccurrencesOfString:withString:options:range:
NSString的方法
-stringByReplacingOccurrencesOfString:withString:
-stringByReplacingOccurrencesOfString:withString:options:range:
-stringByReplacingCharactersInRange:withString:
NSMutableString不会创建新字符串,性能会好点
NSMutableString *string;
// 假设我们已经有了一个名为 string 的字符串
// 现在要去掉它的一个前缀,做法如下:
NSString *prefix = @
"WeDon’tWantThisPrefix"
NSRange r = [string rangeOfString:prefix options:NSAnchoredSearch range:NSMakeRange(0, string.length) locale:nil];
if
(r.location != NSNotFound) {
[string deleteCharactersInRange:r];
}
连接字符串
NSArray *names = @[
"Hildr"
, @
"Heidrun"
, @
"Gerd"
, @
"Guðrún"
, @
"Freya"
, @
"Nanna"
, @
"Siv"
, @
"Skaði"
, @
"Gróa"
];
NSString *result = [names componentsJoinedByString:@
", "
];
字符串解析
正则表达式
NSError *error = nil;
NSString *pattern = @
"(\w+) = #(\p{Hex_Digit}{6})"
;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:&error];
NSTextCheckingResult *result = [expression firstMatchInString:string
options:0
range:NSMakeRange(0, string.length)];
NSString *key = [string substringWithRange:[result rangeAtIndex:1]];
NSString *value = [string substringWithRange:[result rangeAtIndex:2]];
将字符串分解成数组,使用componentsSeparatedByString:这个方法,或者 enumerateSubstringsInRange:options:usingBlock:。如果是按照行来进行分解可以使用option这个参数 传NSStringEnumerationByLines
NSString *input = @“
backgroundColor =
#ff0000
textColor =
#0000ff
"
NSString *pattern = @"
(\w+) =
#([\da-f]{6})";
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:NULL];
NSArray *lines = [input componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for
(NSString *line
in
lines) {
NSTextCheckingResult *textCheckingResult = [expression firstMatchInString:line
options:0
range:NSMakeRange(0, line.length)];
NSString* key = [line substringWithRange:[textCheckingResult rangeAtIndex:1]];
NSString* value = [line substringWithRange:[textCheckingResult rangeAtIndex:2]];
result[key] = value;
}
return
result;
扫描
NSScanner
NSScanner *scanner = [NSScanner scannerWithString:string];
//默认情况下,扫描器会跳过所有空格符和换行符。但这里我们只希望跳过空格符
scanner.charactersToBeSkipped = [NSCharacterSet whitespaceCharacterSet];
//定义一个十六进制字符集
NSCharacterSet *hexadecimalCharacterSet =
[NSCharacterSet characterSetWithCharactersInString:@
"0123456789abcdefABCDEF"
];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
while
(!scanner.isAtEnd) {
NSString *key = nil;
NSString *value = nil;
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
BOOL didScan = [scanner scanCharactersFromSet:letters intoString:&key] &&
[scanner scanString:@
"="
intoString:NULL] &&
[scanner scanString:@
"#"
intoString:NULL] &&
[scanner scanCharactersFromSet:hexadecimalCharacterSet intoString:&value] &&
value.length == 6;
result[key] = value;
[scanner scanCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:NULL];
// 继续扫描下一行
}
return
result;
解析器
设计一个能够用(100,0,255)或者#ff0000这样的字符来定义颜色的方法。
- (NSDictionary *)parse:(NSString *)string error:(NSError **)error
{
self.scanner = [NSScanner scannerWithString:string];
self.scanner.charactersToBeSkipped = [NSCharacterSet whitespaceCharacterSet];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet]
while
(!self.scanner.isAtEnd) {
NSString *key = nil;
UIColor *value = nil;
BOOL didScan = [self.scanner scanCharactersFromSet:letters intoString:&key] &&
[self.scanner scanString:@
"="
intoString:NULL] &&
[self scanColor:&value];
result[key] = value;
[self.scanner scanCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:NULL];
// 继续扫描下一行
}
}
- (BOOL)scanColor:(UIColor **)out
{
return
[self scanHexColorIntoColor:out] || [self scanTupleColorIntoColor:out];
}
//扫描设置#ff0000这样的
- (BOOL)scanHexColorIntoColor:(UIColor **)out
{
NSCharacterSet *hexadecimalCharacterSet =
[NSCharacterSet characterSetWithCharactersInString:@
"0123456789abcdefABCDEF"
];
NSString *colorString = NULL;
if
([self.scanner scanString:@
"#"
intoString:NULL] &&
[self.scanner scanCharactersFromSet:hexadecimalCharacterSet
intoString:&colorString] &&
colorString.length == 6) {
*out = [UIColor colorWithHexString:colorString];
return
YES;
}
return
NO;
}
- (BOOL)scanTupleColorIntoColor:(UIColor **)out
{
NSInteger red, green, blue = 0;
BOOL didScan = [self.scanner scanString:@
"("
intoString:NULL] &&
[self.scanner scanInteger:&red] &&
[self.scanner scanString:@
","
intoString:NULL] &&
[self.scanner scanInteger:&green] &&
[self.scanner scanString:@
","
intoString:NULL] &&
[self.scanner scanInteger:&blue] &&
[self.scanner scanString:@
")"
intoString:NULL];
if
(didScan) {
*out = [UIColor colorWithRed:(CGFloat)red/255.
green:(CGFloat)green/255.
blue:(CGFloat)blue/255.
alpha:1];
return
YES;
}
else
{
return
NO;
}
}
符号化处理
先进星扫描,使用NSScanner来解析这个表达式
myView.left = otherView.right * 2 + 10
viewController.view.centerX + myConstant <= self.view.centerX
NSScanner *scanner = [NSScanner scannerWithString:contents];
NSMutableArray *tokens = [NSMutableArray array];
while
(![scanner isAtEnd]) {
for
(NSString *operator
in
@[@
"="
, @
"+"
, @
"*"
, @
">="
, @
"<="
, @
"."
]) {
if
([scanner scanString:operator intoString:NULL]) {
[tokens addObject:operator];
}
}
}
//接下来识别非符号的只包含字母的string
NSString *result = nil;
if
([scanner scanCharactersFromSet:[NSCharacterSet letterCharacterSet]
intoString:&result]) {
[tokens addObject:result];
}
//NSScanner有scanDouble:来扫描double
double doubleResult = 0;
if
([scanner scanDouble:&doubleResult]) {
[tokens addObject:@(doubleResult)];
}
//完成后用将需要解析的表达式放入试试
NSString* example = @
"myConstant = 100
"
@
"
myView.left = otherView.right * 2 + 10
"
@
"viewController.view.centerX + myConstant <= self.view.centerX"
;
NSArray *result = [self.scanner tokenize:example];
NSArray *expected = @[@
"myConstant"
, @
"="
, @100, @
"myView"
, @
"."
, @
"left"
,
@
"="
, @
"otherView"
, @
"."
, @
"right"
, @
"*"
, @2, @
"+"
,
@10, @
"viewController"
, @
"."
, @
"view"
, @
"."
,
@
"centerX"
, @
"+"
, @
"myConstant"
, @
"<="
, @
"self"
,
@
"."
, @
"view"
, @
"."
, @
"centerX"
];
XCTAssertEqualObjects(result, expected);
进行语法解析,需要语法分析库描述我们的语言。下面代码就是为那个布局约束语言写的解析语法,用的扩展的巴科斯范式EBNF写法:
constraint = expression comparator expression
comparator =
"="
|
">="
|
"<="
expression = keyPath
"."
attribute addMultiplier addConstant
keyPath = identifier | identifier
"."
keyPath
attribute =
"left"
|
"right"
|
"top"
|
"bottom"
|
"leading"
|
"trailing"
|
"width"
|
"height"
|
"centerX"
|
"centerY"
|
"baseline"
addMultiplier =
"*"
atom
addConstant =
"+"
atom
atom = number | identifier
还有很多Objective-C的语法解析,更多的可以在CocoaPods上找到:http://cocoapods.org/?q=parse。比较好的就是CoreParse,地址:https://github.com/beelsebob/CoreParse,但是需要使用它支持的语法。下面就是CoreParse支持的格式:
NSString* grammarString = [@[
@
"Atom ::= num@'Number' | ident@'Identifier';"
,
@
"Constant ::= name@'Identifier' '=' value@<Atom>;"
,
@
"Relation ::= '=' | '>=' | '<=';"
,
@
"Attribute ::= 'left' | 'right' | 'top' | 'bottom' | 'leading' | 'trailing' | 'width' | 'height' | 'centerX' | 'centerY' | 'baseline';"
,
@
"Multiplier ::= '*' num@'Number';"
,
@
"AddConstant ::= '+' num@'Number';"
,
@
"KeypathAndAttribute ::= 'Identifier' '.' <AttributeOrRest>;"
,
@
"AttributeOrRest ::= att@<Attribute> | 'Identifier' '.' <AttributeOrRest>;"
,
@
"Expression ::= <KeypathAndAttribute> <Multiplier>? <AddConstant>?;"
,
@
"LayoutConstraint ::= lhs@<Expression> rel@<Relation> rhs@<Expression>;"
,
@
"Rule ::= <Atom> | <LayoutConstraint>;"
,
] componentsJoinedByString:@
"
"
];
一个规则匹配后解析器就找到同样名称的类
- (id)parser:(CPParser *)parser didProduceSyntaxTree:(CPSyntaxTree *)syntaxTree
NSString *ruleName = syntaxTree.rule.name;
if
([ruleName isEqualToString:@
"Attribute"
]) {
return
self.layoutAttributes[[[syntaxTree childAtIndex:0] keyword]];
}
...
}
完整的解析器代码在:https://github.com/objcio/issue-9-string-parsing。里面有个解析类可以用来解析复杂的布局约束,如下:
viewController.view.centerX + 20 <= self.view.centerX * 0.5
可以得到如下结果,方便转换成NSLayoutConstraint对象
(<Expression: self.keyPath=(viewController, view),
self.attribute=9,
self.multiplier=1,
self.constant=20>
-1
<Expression: self.keyPath=(self, view),
self.attribute=9,
self.multiplier=0.5,
self.constant=0>)
字符串的渲染
UILabel
label默认显示一行,如果设置numberOfLines为大于1的话可以显示指定行数,如果设置为0,则多少行都显示
attributedText属性可以显示富文本
label的font,textColor,textAlignment,shadowColor和shadowOffset属性可以改变外观。
改变程序内所有Label的风格,可以使用[UILabel appearance]方法
UITextField
text field只限于单行
UITextfield实现了UITextInputTraits协议,这个协议需要指定键盘外观和操作等细节。比如显示什么键盘和返回按键响应等
可以通过设置左右辅助视图,或者设置背景来自定义输入框风格了。
UITextView
相比较UITextField,它能够处理多行文本
可以使用定制Text Kit,官方文档:https://developer.apple.com/Library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html
可以为layout manager,text container或text storage自定义行为或替换自定义子类。
在iOS7之前是基于WebKit的功能少,之后会有很多不同具体可以参考这两篇文章:Peter的http://petersteinberger.com/blog/2014/fixing-uitextview-on-ios-7/,Brent的http://inessential.com/2014/01/07/uitextview_the_solution
TableView中显示动态文本
Table view的Delegate有个方法用来计算高度:tableView:heightForRowAtIndexPath:。自定义一个UITableViewCell的子类
- (void)layoutSubviews
{
[
super
layoutSubviews];
self.textLabel.frame = CGRectInset(self.bounds,
MyTableViewCellInset,
MyTableViewCellInset);
}
计算真实高度需要使用boundingRectWithSize:options:context: 这个方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat labelWidth = self.tableView.bounds.size.width - MyTableViewCellInset*2;
NSAttributedString *text = [self attributedBodyTextAtIndexPath:indexPath];
NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingUsesFontLeading;
CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
options:options
context:nil];
return
(CGFloat) (ceil(boundingRect.size.height) + MyTableViewCellInset*2);
}
使用Text Kit和NSAttributedString进行布局
先设置attributes
CGFloat const fontSize = 15;
NSMutableDictionary *body1stAttributes = [NSMutableDictionary dictionary];
body1stAttributes[NSFontAttributeName] = [UIFont fontWithName:@
"BodoniSvtyTwoITCTT-Book"
size:fontSize];
NSMutableParagraphStyle *body1stParagraph = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
body1stParagraph.alignment = NSTextAlignmentJustified;
body1stParagraph.minimumLineHeight = fontSize + 3;
body1stParagraph.maximumLineHeight = body1stParagraph.minimumLineHeight;
body1stParagraph.hyphenationFactor = 0.97;
body1stAttributes[NSParagraphStyleAttributeName] = body1stParag
raph;
这里字体为BodoniSvtyTwoITCTT,如果需要查看更多字体可以使用 +[UIFont familyNames]这个方法。为了得到字体的名字,可以使用 +[UIFont fontNamesForFamilyName:]。接下来创建段落的属性
NSMutableDictionary *bodyAttributes = [body1stAttributes mutableCopy];
NSMutableParagraphStyle *bodyParagraph =
[bodyAttributes[NSParagraphStyleAttributeName] mutableCopy];
bodyParagraph.firstLineHeadIndent = fontSize;
bodyAttributes[NSParagraphStyleAttributeName] = bodyParagraph;
装饰段落风格,使用装饰字体将文本居中对齐,装饰字符的前后加上空白段落
NSMutableDictionary *ornamentAttributes = [NSMutableDictionary dictionary];
ornamentAttributes[NSFontAttributeName] = [UIFont fontWithName:@
"BodoniOrnamentsITCTT"
size:36];
NSMutableParagraphStyle *ornamentParagraph = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
ornamentParagraph.alignment = NSTextAlignmentCenter;
ornamentParagraph.paragraphSpacingBefore = fontSize;
ornamentParagraph.paragraphSpacing = fontSize;
ornamentAttributes[NSParagraphStyleAttributeName] = ornamentParagraph;
显示数字表格table,表格布局示例
NSCharacterSet *decimalTerminator = [NSCharacterSet
characterSetWithCharactersInString:decimalFormatter.decimalSeparator];
NSTextTab *decimalTab = [[NSTextTab alloc]
initWithTextAlignment:NSTextAlignmentCenter
location:100
options:@{NSTabColumnTerminatorsAttributeName:decimalTerminator}];
NSTextTab *percentTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentRight
location:200
options:nil];
NSMutableParagraphStyle *tableParagraphStyle =
[[NSParagraphStyle defaultParagraphStyle] mutableCopy];
tableParagraphStyle.tabStops = @[decimalTab, percentTab];
显示列表的属性设置如下
NSMutableDictionary *listAttributes = [bodyAttributes mutableCopy];
NSMutableParagraphStyle *listParagraph =
[listAttributes[NSParagraphStyleAttributeName] mutableCopy];
listParagraph.headIndent = fontSize * 3;
listParagraph.firstLineHeadIndent = fontSize;
NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural
location:fontSize * 3
options:nil];
listParagraph.tabStops = @[listTab];
listAttributes[NSParagraphStyleAttributeName] = listParagraph;
- iOS 字符串常用操作总结
- iOS 字符串常用操作
- iOS 字符串常用操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- ios 常用字符串的操作
- iOS字符串常用操作集合
- ios 常用字符串的操作
- ios 常用字符串的操作
- Js字符串常用操作总结
- 5天学会jaxws-webservice编程第四天
- 平衡三进制
- Installation failed due to invalid APK file!问题解决
- webpack hot-update.json failed.解决办法
- css vertical-align属性
- iOS 字符串常用操作总结
- SIP对话调试
- 13. 精度
- 5天学会jaxws-webservice编程第五天
- 你可以拥有自己想要的生活
- 算法#19--霍夫曼压缩(数据压缩)
- 微信应用号即将推出:“应用号”能直接被搜索?
- QComboBox下拉框虚线去除的两种处理方法
- 第四周 项目五【猴子选大王】