编程语言对比系列:一、字符串的基本使用

前言

最先接触编程的知识是在大学里面,大学里面学了一些基础的知识,c语言,java语言,单片机的汇编语言等;大学毕业后就开始了app的开发之路,先使用oc进行iOSapp开发,后面应公司需求,又相继学习了java语言并使用java语言进行Androidapp开发,后来微信开放了小程序,应公司需求,又学习了小程序的相关知识,jscsshtml等,脑袋里面有了这么多的编程语言,有时候会有点混乱,因此想到了把这些编程语言的一些内容进行对比、梳理,可以找到他们的相同点和不同点,结果是很好的,让自己的知识更加有深度了,也更加全面了。这篇文章是第一篇,选择的是字符串string,后续会继续更新其他内容的对比。

正在前往全栈的路上!!!

编程语言对比系列:一、字符串的基本使用

大纲为

image

名词解释

  • code point : 用来表示unicode编码表中的字符character的一个十六进制的数字(日常使用中十六进制、进制数字都是可以的),a hexadecimal number that is used to represent that character in computer data, 如 :

    code point 0x4E00 对应的 character ;

    code point 0x41 对应的 characterA ;

  • code unit : 表示一个unicode编码表中的字符character所需要的二进制位数bitsA Unicode code unit is a bit size used by a particular Unicode encoding,For example UTF-8 has a code unit size of 8 bits and UTF-16 has 16 and UTF-32 has 32,也可以理解为识别一个unicode字符所需要的二进制位数bits,不够的会被舍弃掉

  • code point —> code unit —> string

属性/方法

一、初始化

OC init

通用

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

初始化一个的字符串 @""

  • 方法
- (instancetype)init NS_DESIGNATED_INITIALIZER;
+ (instancetype)string;
  • 例子
NSString *str;
NSString *str2;
NSLog(@"%@", str);
NSLog(@"%@", str2);
NSLog(@"-----------");
str = [[NSString alloc] init];
str2 = [NSString string];
NSLog(@"%@", str);
NSLog(@"%@", str2);
NSLog(@"-----------");

//打印:
(null)
(null)
-----------


-----------

二进制 NSData (准确的说应该是十六进制

  • 方法
- (nullable instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
  • 例子
NSData *data = [@"one" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", data);
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);

//打印:
<6f6e65>
one

//如果编码方式为 NSUnicodeStringEncoding :
<6f6e65>
潮
  • 小结
    • 同样的二进制数据,因为编码方式的不同,获取到的结果也不同,优先使用NSUTF8StringEncoding

    • 编码方式对应的所需字节数如下:

      • UTF-8编码方式处理二进制数6f6e656f6e65,看成是三个单元处理,在ASCII码表中对应的值依次为one,所以输出one
      • Unicode编码方式处理二进制数6f6e656f6e 65,看成是两个单元处理,一个是完整的6f6e(保留),一个不是完整的65(舍弃),在Unicode编码表中对应的值为汉字,所以输出
      • 所以得到的结果如上,?

通过字节bytes

  • 方法
//bytes : 字节数,从缓存buffer中读取,是指向buffer地址的指针,指向的是在缓存中的地址
//len : 需要读取bytes的长度,如bytes为3,len参数为1,则只会读取bytes中的前1个byte
//encoding : 编码方式
//freeBuffer : 操作之后是否释放掉内存
- (nullable instancetype)initWithBytes:(const void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding;
- (nullable instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)freeBuffer;    /* "NoCopy" is a hint */
  • 例子
NSData *data = [@"one" dataUsingEncoding:NSUTF8StringEncoding];
const void *bytes = [data bytes];
NSLog(@"%p", bytes);

NSString *str = [[NSString alloc] initWithBytes:bytes length:data.length encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);

//输出:
0x6000000035e0
one

当length参数传1时
0x600000017600
o
  • 小结
    • 从缓存buffer中读取length长度的字节bytes构建字符串

字符characters

  • 方法
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer; /* "NoCopy" is a hint */
- (instancetype)initWithCharacters:(const unichar *)characters length:(NSUInteger)length;
+ (instancetype)stringWithCharacters:(const unichar *)characters length:(NSUInteger)length;
  • 例子
// 43 、0x2b 、'+' 这些输出的都是 + 
const unichar ch = 43;
NSString *str = [[NSString alloc] initWithCharacters:&ch length:3];
NSLog(@"%@", str);
//输出:
+
  
  
unichar ch[3];
ch[0] = '+';
ch[1] = 43;
ch[2] = 0x2b;
NSString *str = [[NSString alloc] initWithCharacters:ch length:sizeof(ch) / sizeof(unichar)];
NSLog(@"%@", str);
// 输出:
+++
  • 小结
    • 通过 unicode 字符构建字符串,可以使用 十六进制十进制字符

通过OC字符串 NSString

  • 方法
//通过其他"oc字符串"初始化
- (instancetype)initWithString:(NSString *)aString;
+ (instancetype)stringWithString:(NSString *)string;
  
//通过其他"oc字符串"初始化,带有参数的,可以作为字符串拼接使用
- (instancetype)initWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
- (instancetype)initWithFormat:(NSString *)format arguments:(va_list)argList NS_FORMAT_FUNCTION(1,0);
+ (instancetype)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
  
//带有本地话的初始化
- (instancetype)initWithFormat:(NSString *)format locale:(nullable id)locale, ... NS_FORMAT_FUNCTION(1,3);
- (instancetype)initWithFormat:(NSString *)format locale:(nullable id)locale arguments:(va_list)argList NS_FORMAT_FUNCTION(1,0);
+ (instancetype)localizedStringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
  • 例子
//通过其他“oc字符串”直接量初始化
NSString *str = [[NSString alloc] initWithString:@"one"];
NSLog(@"%@", str);
NSString *str2 = [NSString stringWithString:@"one"];
NSLog(@"%@", str2);
  
//输出:
one
one
  
  
//
int age = 18;
NSString *ageStr = [NSString stringWithFormat:@"小明今年%d岁", age];
NSLog(@"%@", ageStr);
  
//输出:
小明今年18岁
  • 小结
    • 如果是通过字符串常量进行初始化,不推荐使用上面方法,使用下面的写法

          NSString *str = @"one";
      

c字符串CString

  • 方法
//把c字符串用encoding编码方式转化为OC字符串
- (nullable instancetype)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
+ (nullable instancetype)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc;
  
//把c字符串用UTF-8编码方式转化为OC字符串
- (nullable instancetype)initWithUTF8String:(const char *)nullTerminatedCString;
+ (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
  • 例子
//按照指定编码方式把c字符串转化为oc字符串
const char *cStr = "c string";
NSString *str = [NSString stringWithCString:cStr encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);
  
//输出
c string
  
//如果使用的是NSUnicodeStringEncoding编码方式,输出为:
挠獴物湧
  
  
  
//按照UTF-8编码方式把c字符串转化为oc字符串
const char *cStr = "c string";
NSString *str = [NSString stringWithUTF8String:cStr];
NSLog(@"%@", str);
  
//输出:
c string
  • 小结
    • 相同的c字符串,使用不同的编码方式得到的结果不一样,优先使用NSUTF8StringEncoding编码方式

通过URLNSURL

  • 方法

          //使用指定的编码方式
          - (nullable instancetype)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;
          + (nullable instancetype)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;
          
          - (nullable instancetype)initWithContentsOfURL:(NSURL *)url usedEncoding:(nullable NSStringEncoding *)enc error:(NSError **)error;
          + (nullable instancetype)stringWithContentsOfURL:(NSURL *)url usedEncoding:(nullable NSStringEncoding *)enc error:(NSError **)error;
          
          // 把字符串写入到url的方法为:
          - (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
    
  • 例子

          NSURL *url = [NSURL URLWithString:@"https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html#//apple_ref/doc/uid/10000051i-CH6"];
          NSError *error = nil;
          NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
          if (!error) {
              NSLog(@"成功---");
              NSLog(@"%@", str);
          } else {
              NSLog(@"失败---");
          }
          
          //输出:
          成功---
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <title>String Resources</title>
              <meta http-equiv="X-UA-Compatible" content="IE=7">
              <meta charset="utf-8">
              <meta id="book-resource-type" name="book-resource-type" content="Guide">
              <meta scheme="apple_ref" id="identifier" name="identifier" content="//apple_ref/doc/uid/10000051i">
              <meta id="document-version" name="document-version" content="7.5.1">
              <meta id="build" name="build" content="616ed7ce2df6736fb09643756e2ae753" />
              <meta id="chapterId" name="chapterId" content="10000051i-CH6">
              <meta id="date" name="date" content="2016-03-21">
              <meta id="description" name="description" content="Explains how to work with nib and bundle resources in apps.">
              <meta id="book-title" name="book-title" content="Resource Programming Guide">
              <meta id="book-root" name="book-root" content="../">
              <meta id="book-json" name="book-json" content="../book.json">
              <meta id="devcenter" name="devcenter" content="Mac Dev Center">
              <meta id="devcenter-url" name="devcenter-url" content="http://developer.apple.com/devcenter/mac">
              <meta id="reflib" name="reflib" content="Guides and Sample Code">
              <meta id="book-assignments" name="book-assignments" content="{Type/Guide}, {Topic/Data Management/File Management}">
              
              
              <meta id="copyright" name="copyright" content="Copyright 2018 Apple Inc. All Rights Reserved.">
              <meta id="xcode-display" name="xcode-display" content="render">
              <meta id="IndexTitle" name="IndexTitle" content="Resource Programming Guide: String Resources">
              <meta id="resources-uri" name="resources-uri" content="../../../../../Resources/1274">
              <link id="book-index-page" rel="Start" title="Resource Programming Guide" type="text/html" href="../index.html">
              <link id="next-page" rel="Next" type="text/html" href="../ImageSoundResources/ImageSoundResources.html">
              <link id="previous-page" rel="Prev" type="text/html" href="../CocoaNibs/CocoaNibs.html">
              <link rel="stylesheet" type="text/css" href="../../../../../Resources/1274/CSS/screen.css">
              
              <!-- xcode_css -->
              <link rel="stylesheet" type="text/css" href="../../../../../Resources/1274/CSS/feedback.css">
              <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
              <meta id="platforms" name="platforms" content="">
          </head>    
          <body><a name="//apple_ref/doc/uid/10000051i-CH6" title="String Resources"></a>
              <div id="_omniture_top">
              <!-- SiteCatalyst code version: H.8. Copyright 1997-2006 Omniture, Inc. -->
              <script type="text/javascript">
              /* RSID: */
              var s_account="appleglobal,appleusdeveloper,dappdeveloperlib"
              </script>
          
              <script type="text/javascript" src="https://www.apple.com/metrics/scripts/s_code_h.js"></script>
              <script type="text/javascript">
              s.pageName=AC.Tracking.pageName();
              s.channel="www.us.developer"
          
              /************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
              var s_code=s.t();if(s_code)document.write(s_code)</script>
              <!-- End SiteCatalyst code version: H.8. -->
              </div>
          
              <div id="adcHeader" class="hideOnPrint hideInXcode">
                  <div id='ssi_Header' class="hideInXcode unified">
                      <a id="ssi_LibraryTitle" href='../../../../../navigation/'>Guides and Sample Code</a>
                      <a id="ssi_AppleDeveloperConnection" href='https://developer.apple.com/'>Developer</a>
                      <div id='ssi_SearchButton' role="button" title="Search">Search</div>
                  </div>
                  <form id='ssi_SearchMenu' method='get' action='../../../../../search/' accept-charset='utf-8'>
                      <label for='adcsearch'>Search Guides and Sample Code</label>
                      
                      
              
                      <input type='search' id='ssi_SearchField' name='q' accesskey='s' results='5' />
                  </form>
              </div>
          
              <header id="header">
                  <div id="title" role="banner">
                      <h1>Resource Programming Guide</h1>
                      <span id="file_links">
                          <a id="PDF_link" role="button" tabindex='4' rel="alternate" title="Download PDF"><span id="pdf_icon"></span>PDF</a>
                          <a id="Companion_link" role="button" tabindex='3' title="Download Companion File"><span id="companion_icon"></span>Companion File</a>
                      </span>
                  </div>
                  <ul id="headerButtons" class="hideOnPrint" role="toolbar">
                      <li id="toc_button" style="display:none">
                          <button tabindex="5" id="table_of_contents" class="open" role="checkbox" aria-label="Show Table of Contents"><span class="disclosure"></span>Table of Contents</button>
                      </li>
                      <li id="jumpto_button" style="display:none" role="navigation"><select tabindex="6" id="jumpTo"><option value="top">Jump To&#133;</option></select></li>
                      <li id="downloadSample_button" style="display:none">
                          <a id="Sample_link"><button id="Sample_button">Download Sample Code</button></a>
                      </li>
                  </ul>
              </header>
              <nav id="tocContainer" tabindex="7">
                  <ul id="toc" role="tree"></ul>
              </nav>
          
              <article id="contents" tabindex="0" role="main">
                  <div id="pageNavigationLinks_top" class="pageNavigationLinks">
                      <a class='nextLink' rel='next' href='../ImageSoundResources/ImageSoundResources.html'>Next</a><a class='previousLink' rel='prev' href='../CocoaNibs/CocoaNibs.html'>Previous</a>
                  </div>
                  <a id="top" name="top"></a>
                  <a id="INDEX" href="../index.html" style="display:none;"></a>
                  
                  <a name="//apple_ref/doc/uid/10000051i-CH6-SW1" title="String Resources"></a><h1 id="pageTitle">String Resources</h1><p><a name="//apple_ref/doc/uid/10000051i-CH6-DontLinkElementID_5"></a><a name="//apple_ref/doc/uid/10000051i-CH6-DontLinkElementID_6"></a>An important part of the localization process is to localize all of the text strings displayed by your application. By their nature, strings located in <span class="pediaLink" data-header="Nib file" data-contents="A nib file is a special type of resource file that you use to store the user interfaces of iOS and Mac apps. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/NibFile.html#//apple_ref/doc/uid/TP40008195-CH34" data-renderer-version="1" target="_self">nib files</a></span> can be readily localized along with the rest of the nib file contents. Strings embedded in your code, however, must be extracted, localized, and then reinserted back into your code. To simplify this process—and to make the maintenance of your code easier—OS X and iOS provide the infrastructure needed to separate strings from your code and place them into resource files where they can be localized easily.</p><p>Resource files that contain localizable strings are referred to as <em class="newTerm">strings</em> files because of their filename extension, which is <code>.strings</code>. You can create strings files manually or programmatically depending on your needs. The standard strings file format consists of one or more key-value pairs along with optional comments. The key and value in a given pair are strings of text enclosed in double quotation marks and separated by an equal sign. (You can also use a property list format for strings files. In such a case, the top-level node is a dictionary and each key-value pair of that dictionary is a string entry.) </p><p><span class="content_text">Listing 2-1</span> shows a simple strings file that contains non-localized entries for the default language. When you need to display a string, you pass the string on the left to one of the available string-loading routines. What you get back is the matching value string containing the text translation that is most appropriate for the current user. For the development language, it is common to use the same string for both the key and value, but doing so is not required.</p><a name="//apple_ref/doc/uid/10000051i-CH6-SW7" title="Listing 2-1A simple strings file"></a><p class="codesample clear"><strong class="caption_number">Listing 2-1</strong>&nbsp;&nbsp;A simple strings file</p><div class="codesample clear"><table><tr><td scope="row"><pre>/* Insert Element menu item */<span></span></pre></td></tr><tr><td scope="row"><pre>"Insert Element" = "Insert Element";<span></span></pre></td></tr><tr><td scope="row"><pre>/* Error string used for unknown error types. */<span></span></pre></td></tr><tr><td scope="row"><pre>"ErrorString_1" = "An unknown error occurred.";<span></span></pre></td></tr></table></div><p>A typical application has at least one strings file per localization, that is, one strings file in each of the <span class="pediaLink" data-header="Bundle" data-contents="A bundle is a directory in the file system that groups executable code and related resources such as images and sounds together in one place. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/Bundle.html#//apple_ref/doc/uid/TP40008195-CH4" data-renderer-version="1" target="_self">bundle’s</a></span> <code>.lproj</code> subdirectories. The name of the default strings file is <code><a name="//apple_ref/doc/uid/10000051i-CH6-DontLinkElementID_7"></a>Localizable.strings</code> but you can create strings files with any file name you choose. Creating strings files is discussed in more depth in <span class="content_text"><a href="#//apple_ref/doc/uid/10000051i-CH6-SW5" data-renderer-version="1">Creating Strings Resource Files</a></span>. </p><div class="notebox"><aside><a name="//apple_ref/doc/uid/10000051i-CH6-SW4" title="Note"></a><p><strong>Note:</strong>&nbsp;It is recommended that you save strings files using the UTF-8 encoding, which is the default encoding for standard strings files. Xcode automatically transcodes strings files from UTF-8 to UTF-16 when they’re copied into the product. For more information about the standard strings file format, see <span class="content_text"><a href="#//apple_ref/doc/uid/10000051i-CH6-SW5" data-renderer-version="1">Creating Strings Resource Files</a></span>. For more information about Unicode and its text encodings, go to <span class="content_text"><a href="http://www.unicode.org/" class="urlLink" rel="external">http://www.unicode.org/</a></span> or <span class="content_text"><a href="http://en.wikipedia.org/wiki/Unicode" class="urlLink" rel="external">http://en.wikipedia.org/wiki/Unicode</a></span>.</p><p></p></aside></div><p>The loading of string resources (both localized and nonlocalized) ultimately relies on the bundle and internationalization support found in both OS X and iOS. For information about bundles, see <em><a href="../../../../CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html#//apple_ref/doc/uid/10000123i" data-renderer-version="1" target="_self">Bundle Programming Guide</a></em>. For more information about internationalization and localization, see <em><a href="../../../../MacOSX/Conceptual/BPInternational/Introduction/Introduction.html#//apple_ref/doc/uid/10000171i" data-renderer-version="1" target="_self">Internationalization and Localization Guide</a></em>. </p><section><a name="//apple_ref/doc/uid/10000051i-CH6-SW5" title="Creating Strings Resource Files"></a><h2 class="jump">Creating Strings Resource Files</h2><p>Although you can create strings files manually, it is rarely necessary to do so. If you write your code using the appropriate string-loading macros, you can use the <code>genstrings</code> command-line tool to extract those strings and create strings files for you. </p><p>The following sections describe the process of how to set up your source files to facilitate the use of the <code>genstrings</code> tool. For detailed information about the tool, see <code><!--a target="_self" -->genstrings<!--/a--></code> man page.</p><section><a name="//apple_ref/doc/uid/10000051i-CH6-96936" title="Choosing Which Strings to Localize"></a><h3 class="jump">Choosing Which Strings to Localize</h3><p>When it comes to localizing your application’s interface, it is not always appropriate to localize every string used by your application. Translation is a costly process, and translating strings that are never seen by the user is a waste of time and money. Strings that are not displayed to the user, such as notification names used internally by your application, do not need to be translated. Consider the following example: </p><div class="codesample clear"><table><tr><td scope="row"><pre>if (CFStringHasPrefix(value, CFSTR("-")) {    CFArrayAppendValue(myArray, value);};<span></span></pre></td></tr></table></div><p>In this example, the string “<code>-</code>” is used internally and is never seen by the user; therefore, it does not need to be placed in a strings file. </p><p>The following code shows another example of a string the user would not see. The string <code>"%d %d %s"</code> does not need to be localized, since the user never sees it and it has no effect on anything that the user does see. </p><div class="codesample clear"><table><tr><td scope="row"><pre>matches = sscanf(s, "%d %d %s", &amp;first, &amp;last, &amp;other);<span></span></pre></td></tr></table></div><p>Because nib files are localized separately, you do not need to include strings that are already located inside of a nib file. Some of the strings you should localize, however, include the following:</p><ul class="ul"><li class="li"><p>Strings that are programmatically added to a window, panel, view, or control and subsequently displayed to the user. This includes strings you pass into standard routines, such as those that display alert boxes.</p></li><li class="li"><p>Menu item title strings if those strings are added programmatically. For example, if you use custom strings for the Undo menu item, those strings should be in a strings file. </p></li><li class="li"><p>Error messages that are displayed to the user.</p></li><li class="li"><p>Any boilerplate text that is displayed to the user.</p></li><li class="li"><p>Some strings from your application’s information property list (<code>Info.plist</code>) file; see <em><a href="../../../../MacOSX/Conceptual/BPRuntimeConfig/000-Introduction/introduction.html#//apple_ref/doc/uid/10000170i" data-renderer-version="1" target="_self">Runtime Configuration Guidelines</a></em>.</p></li><li class="li"><p>New file and document names.</p></li></ul></section><section><a name="//apple_ref/doc/uid/10000051i-CH6-SW8" title="About the String-Loading Macros"></a><h3 class="jump">About the String-Loading Macros</h3><p>The Foundation and Core Foundation <span class="pediaLink" data-header="Framework" data-contents="A framework is a bundle (a structured directory) that contains a dynamic shared library along with associated resources, such as nib files, image files, and header files. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/Framework.html#//apple_ref/doc/uid/TP40008195-CH56" data-renderer-version="1" target="_self">frameworks</a></span> define the following macros to make loading strings from a strings file easier:</p><ul class="ul"><li class="li"><p>Core Foundation macros:</p><ul class="nested"><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/corefoundation/cfcopylocalizedstring" target="_self" class="urlLink">CFCopyLocalizedString</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/corefoundation/cfcopylocalizedstringfromtable" target="_self" class="urlLink">CFCopyLocalizedStringFromTable</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/corefoundation/cfcopylocalizedstringfromtableinbundle" target="_self" class="urlLink">CFCopyLocalizedStringFromTableInBundle</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/corefoundation/cfcopylocalizedstringwithdefaultvalue" target="_self" class="urlLink">CFCopyLocalizedStringWithDefaultValue</a></code></p></li></ul></li><li class="li"><p>Foundation macros:</p><ul class="nested"><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/foundation/nslocalizedstring" target="_self" class="urlLink">NSLocalizedString</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/foundation/nslocalizedstringfromtable" target="_self" class="urlLink">NSLocalizedStringFromTable</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/foundation/nslocalizedstringfromtableinbundle" target="_self" class="urlLink">NSLocalizedStringFromTableInBundle</a></code></p></li><li class="nested li"><p><code><a href="https://developer.apple.com/documentation/foundation/nslocalizedstringwithdefaultvalue" target="_self" class="urlLink">NSLocalizedStringWithDefaultValue</a></code></p></li></ul></li></ul><p>You use these macros in your source code to load strings from one of your application’s strings files. The macros take the user’s current language preferences into account when retrieving the actual string value. In addition, the <code>genstrings</code> tool searches for these macros and uses the information they contain to build the initial set of strings files for your application.</p><p>For additional information about how to use these macros, see <span class="content_text"><a href="#//apple_ref/doc/uid/20000005-97055" data-renderer-version="1">Loading String Resources Into Your Code</a></span>.</p></section><section><a name="//apple_ref/doc/uid/10000051i-CH6-SW9" title="Using the genstrings Tool to Create Strings Files"></a><h3 class="jump">Using the genstrings Tool to Create Strings Files</h3><p>At some point during your development, you need to create the strings files needed by your code. If you wrote your code using the Core Foundation and Foundation macros, the simplest way to create your strings files is using the <a name="//apple_ref/doc/uid/10000051i-CH6-DontLinkElementID_8"></a><code>genstrings</code> command-line tool. You can use this tool to generate a new set of strings files or update a set of existing files based on your source code. </p><p>To use the <code>genstrings</code> tool, you typically provide at least two arguments:</p><ul class="ul"><li class="li"><p>A list of source files</p></li><li class="li"><p>An optional output directory</p></li></ul><p>The <code>genstrings</code> tool can parse C, <span class="pediaLink" data-header="Objective-C" data-contents="Objective-C defines a small but powerful set of extensions to the ANSI  C programming language that enables sophisticated object-oriented programming. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/ObjectiveC.html#//apple_ref/doc/uid/TP40008195-CH43" data-renderer-version="1" target="_self">Objective-C</a></span>, and Java code files with the <code>.c</code>, <code>.m</code>, or <code>.java</code> filename extensions. Although not strictly required, specifying an output directory is recommended and is where <code>genstrings</code> places the resulting strings files. In most cases, you would want to specify the directory containing the project resources for your development language. </p><p>The following example shows a simple command for running the <code>genstrings</code> tool. This command causes the tool to parse all Objective-C source files in the current directory and put the resulting strings files in the <code>en.lproj</code> subdirectory, which must already exist. </p><div class="codesample clear"><table><tr><td scope="row"><pre>genstrings -o en.lproj *.m<span></span></pre></td></tr></table></div><p>The first time you run the <code>genstrings</code> tool, it creates a set of new strings files for you. Subsequent runs replace the contents of those strings files with the current string entries found in your source code. For subsequent runs, it is a good idea to save a copy of your current strings files before running <code>genstrings</code>. You can then diff the new and old versions to determine which strings were added to (or changed in) your project. You can then use this information to update any already localized versions of your strings files, rather than replacing those files and localizing them again.   </p><p>Within a single strings file, each key must be unique. Fortunately, the <code>genstrings</code> tool is smart enough to coalesce any duplicate entries it finds. When it discovers a key string used more than once in a single strings file, the tool merges the comments from the individual entries into one comment string and generates a warning. (You can suppress the duplicate entries warning with the <code>-q</code> option.) If the same key string is assigned to strings in different strings files, no warning is generated. </p><p>For more information about using the <code>genstrings</code> tool, see the <code><!--a target="_self" -->genstrings<!--/a--></code> man page. </p></section><section><a name="//apple_ref/doc/uid/10000051i-CH6-SW10" title="Creating Strings Files Manually"></a><h3 class="jump">Creating Strings Files Manually</h3><p>Although the <code>genstrings</code> tool is the most convenient way to create strings files, you can also create them manually. To create a strings file manually, create a new file in TextEdit (or your preferred text-editing application) and save it using the Unicode UTF-8 encoding. (When saving files, TextEdit usually chooses an appropriate encoding by default. To force a specific encoding, you must change the save options in the application preferences.) The contents of this file consists of a set of key-value pairs along with optional comments describing the purpose of each key-value pair. Key and value strings are separated by an equal sign, and the entire entry must be terminated with a semicolon character. By convention, comments are enclosed inside C-style comment delimiters (<code>/*</code> and <code>*/</code>) and are placed immediately before the entry they describe.  </p><p><span class="content_text">Listing 2-2</span> shows the basic format of a strings file. The entries in this example come from the English version of the <code>Localizable.strings</code> file from the TextEdit application. The string on the left side of each equal sign represents the key, and the string on the right side represents the value. A common convention when developing applications is to use a key name that equals the value in the language used to develop the application. Therefore, because TextEdit was developed using the English language, the English version of the <code>Localizable.strings</code> file has keys and values that match.</p><a name="//apple_ref/doc/uid/10000051i-CH6-SW2" title="Listing 2-2Strings localized for English"></a><p class="codesample clear"><strong class="caption_number">Listing 2-2</strong>&nbsp;&nbsp;Strings localized for English</p><div class="codesample clear"><table><tr><td scope="row"><pre>/* Menu item to make the current document plain text */<span></span></pre></td></tr><tr><td scope="row"><pre>"Make Plain Text" = "Make Plain Text";<span></span></pre></td></tr><tr><td scope="row"><pre>/* Menu item to make the current document rich text */<span></span></pre></td></tr><tr><td scope="row"><pre>"Make Rich Text" = "Make Rich Text";<span></span></pre></td></tr></table></div><p><span class="content_text">Listing 2-3</span> shows the German translation of the same entries. These entries also live inside a file called <code>Localizable.strings</code>, but this version of the file is located in the German language project directory of the TextEdit application. Notice that the keys are still in English, but the values assigned to those keys are in German. This is because the key strings are never seen by end users. They are used by the code to retrieve the corresponding value string, which in this case is in German. </p><a name="//apple_ref/doc/uid/10000051i-CH6-SW6" title="Listing 2-3Strings localized for German"></a><p class="codesample clear"><strong class="caption_number">Listing 2-3</strong>&nbsp;&nbsp;Strings localized for German</p><div class="codesample clear"><table><tr><td scope="row"><pre>/* Menu item to make the current document plain text */<span></span></pre></td></tr><tr><td scope="row"><pre>"Make Plain Text" = "In reinen Text umwandeln";<span></span></pre></td></tr><tr><td scope="row"><pre>/* Menu item to make the current document rich text */<span></span></pre></td></tr><tr><td scope="row"><pre>"Make Rich Text" = "In formatierten Text umwandeln";<span></span></pre></td></tr></table></div></section><section><a name="//apple_ref/doc/uid/10000051i-CH6-96996" title="Detecting Non-localizable Strings"></a><h3 class="jump">Detecting Non-localizable Strings</h3><p>AppKit–based applications can take advantage of built-in support to detect strings that do not need to be localized and those that need to be localized but currently are not. To use this built-in support, set user defaults or add launch arguments when running your app. Specify a Boolean value to indicate whether the user default should be enabled or disabled. The available user defaults are as follows:</p><ul class="ul"><li class="li"><p>The <code>NSShowNonLocalizableStrings</code> user default identifies strings that are not localizable. The strings are logged to the shell in upper case. This option occasionally generates some false positives but is still useful overall. </p></li><li class="li"><p>The <code>NSShowNonLocalizedStrings</code> user default locates strings that were meant to be localized but could not be found in the application’s existing strings files. You can use this user default to catch problems with out-of-date localizations. </p></li></ul><p>For example, to use the <code>NSShowNonLocalizedStrings</code> user default with the TextEdit application, enter the following in Terminal:</p><div class="codesample clear"><table><tr><td scope="row"><pre>/Applications/TextEdit.app/Contents/MacOS/TextEdit -NSShowNonLocalizedStrings YES<span></span></pre></td></tr></table></div></section></section><section><a name="//apple_ref/doc/uid/20000005-97055" title="Loading String Resources Into Your Code"></a><a name="//apple_ref/doc/uid/10000051i-CH6-97055-CJBFDJGF" title="Loading String Resources Into Your Code"></a><h2 class="jump">Loading String Resources Into Your Code</h2><p>The Core Foundation and Foundation frameworks provide macros for retrieving both localized and nonlocalized strings stored in strings files. Although the main purpose of these macros is to load strings at runtime, they also serve a secondary purpose by acting as markers that the <code>genstrings</code> tool can use to locate your application’s string resources. It is this second purpose that explains why many of the macros let you specify much more information than would normally be required for loading a string. The <code>genstrings</code> tool uses the information you provide to create or update your application’s strings files automatically. <span class="content_text">Table 2-1</span> lists the types of information you can specify for these routines and describes how that information is used by the <code>genstrings</code> tool. </p><a name="//apple_ref/doc/uid/10000051i-CH6-SW3" title="Table 2-1Common parameters found in string-loading routines"></a><div class="tableholder"><table class="graybox" border = "0" cellspacing="0" cellpadding="5"><caption class="tablecaption"><strong class="caption_number">Table 2-1</strong>&nbsp;&nbsp;Common parameters found in string-loading routines</caption><tr><th scope="col" class="TableHeading_TableRow_TableCell"><p>Parameter</p></th><th scope="col" class="TableHeading_TableRow_TableCell"><p>Description</p></th></tr><tr><td  scope="row"><p>Key</p></td><td ><p>The string used to look up the corresponding value. This string must not contain any characters from the extended ASCII character set, which includes accented versions of ASCII characters. If you want the initial value string to contain extended ASCII characters, use a routine that lets you specify a default value parameter. (For information about the extended ASCII character set, see the corresponding <span class="content_text"><a href="http://en.wikipedia.org/wiki/Extended_ASCII" class="urlLink" rel="external">Wikipedia entry</a></span>.) </p></td></tr><tr><td  scope="row"><p>Table name</p></td><td ><p>The name of the strings file in which the specified key is located. The <code>genstrings</code> tool interprets this parameter as the name of the strings file in which the string should be placed. If no table name is provided, the string is placed in the default <code>Localizable.strings</code> file. (When specifying a value for this parameter, include the filename without the <code>.strings</code> extension.)</p><p>A <code>.strings</code> file whose table name ends with <code>.nocache</code>—for example <code>ErrorNames.nocache.strings</code>—will not have its contents cached by <code><a href="https://developer.apple.com/documentation/foundation/nsbundle" target="_self" class="urlLink">NSBundle</a></code>.</p></td></tr><tr><td  scope="row"><p>Default value</p></td><td ><p>The default value to associate with a given key. If no default value is specified, the <code>genstrings</code> tool uses the key string as the initial value. Default value strings may contain extended ASCII characters. </p></td></tr><tr><td  scope="row"><p>Comment</p></td><td ><p>Translation comments to include with the string. You can use comments to provide clues to the translation team about how a given string is used. The <code>genstrings</code> tool puts these comments in the strings file and encloses them in C-style comment delimiters (<code>/*</code> and <code>*/</code>) immediately above the associated entry.  </p></td></tr><tr><td  scope="row"><p>Bundle</p></td><td ><p>An <code><a href="https://developer.apple.com/documentation/foundation/nsbundle" target="_self" class="urlLink">NSBundle</a></code> object or <code><a href="https://developer.apple.com/documentation/corefoundation/cfbundle" target="_self" class="urlLink">CFBundleRef</a></code> type corresponding to the bundle containing the strings file. You can use this to load strings from bundles other than your application’s main bundle. For example, you might use this to load localized strings from a <span class="pediaLink" data-header="Framework" data-contents="A framework is a bundle (a structured directory) that contains a dynamic shared library along with associated resources, such as nib files, image files, and header files. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/Framework.html#//apple_ref/doc/uid/TP40008195-CH56" data-renderer-version="1" target="_self">framework</a></span> or plug-in.</p></td></tr></table></div><p>When you request a string from a strings file, the string that is returned depends on the available localizations (if any). The Cocoa and Core Foundation macros use the built-in <span class="pediaLink" data-header="Bundle" data-contents="A bundle is a directory in the file system that groups executable code and related resources such as images and sounds together in one place. "><a href="../../../../General/Conceptual/DevPedia-CocoaCore/Bundle.html#//apple_ref/doc/uid/TP40008195-CH4" data-renderer-version="1" target="_self">bundle</a></span> internationalization support to retrieve the string whose localization matches the user’s current language preferences. As long as your localized resource files are placed in the appropriate language-specific project directories, loading a string with these macros should yield the appropriate string automatically. If no appropriate localized string resource is found, the bundle’s loading code automatically chooses the appropriate nonlocalized string instead. </p><p>For information about internationalization in general and how to create language-specific project directories, see <em><a href="../../../../MacOSX/Conceptual/BPInternational/Introduction/Introduction.html#//apple_ref/doc/uid/10000171i" data-renderer-version="1" target="_self">Internationalization and Localization Guide</a></em>. For information about the bundle structure and how resource files are chosen from a bundle directory, see <em><a href="../../../../CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html#//apple_ref/doc/uid/10000123i" data-renderer-version="1" target="_self">Bundle Programming Guide</a></em>.</p><section><a name="//apple_ref/doc/uid/10000051i-CH6-98108" title="Using the Core Foundation Framework"></a><h3 class="jump">Using the Core Foundation Framework</h3><p>The Core Foundation framework defines a single function and several macros for loading localized strings from your application bundle. The <code><a href=
    
  • 小结

    • 通过读取url的内容,并使用响应的编码方式(一般为UTF-8)转化为字符串
    • 如果url内容加载失败,或者编码方式错误,初始化失败,返回nil

通过本地文件file

  • 方法

          //使用指定的编码方式
          - (nullable instancetype)initWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
          + (nullable instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
          
          - (nullable instancetype)initWithContentsOfFile:(NSString *)path usedEncoding:(nullable NSStringEncoding *)enc error:(NSError **)error;
          + (nullable instancetype)stringWithContentsOfFile:(NSString *)path usedEncoding:(nullable NSStringEncoding *)enc error:(NSError **)error;
          
          // 把字符串保存到文件中的方法为
          - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
    
  • 例子

          [//one.text](//one.text) 文件内容为 hello world!
          
          NSError *error = nil;
          NSString *filePath = [[NSBundle mainBundle] pathForResource:@"one.text" ofType:nil];
          NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
          if (!error) {
              NSLog(@"成功---");
              NSLog(@"%@", str);
          } else {
              NSLog(@"失败---");
          }
          
          //输出:
          成功---
          hello world!
    
  • 小结

    • 读取本地文件file内容,并按照响应的编码方式(一般为UTF-8)转化为字符串
    • 如果file内容加载失败,或者编码方式错误,初始化失败,返回nil

Java new String

初始化一个的字符串 ""

      String str = "";

通过字符串String

  • 方法

          public String(String original) { }
    
  • 例子

          String str = new String("hello");
          Log.d("字符串", str);
          
          //输出:
          hello
    
  • 小结

    • 如果是通过一个字符串常量初始化,则不推荐使用上面方法,直接复制即可,如下

          String str = "hello";
      

通过字符char UTF-16 code units

  • 方法

          //字符数组
          public String(char[] value) { }
          
          /**
           *  value - 作为字符源的数组。 
              offset - 初始偏移量。 
              count - 长度。
           */
          //从字符源数组value的offset索引位置处连续取出count长度的的子数组构建字符串
          //如果 offset 和 count 参数索引字符超出 value 数组的范围,则会抛出异常 IndexOutOfBoundsException
          public String(char[] value,
                        int offset,
                        int count)
    
  • 例子

          char[] chars = new char[3];
          chars[0] = 'h';
          chars[1] = 'e';
          chars[2] = '无';
                  
          String str = new String(chars);
          Log.d("字符串", str);
          
          //输出:
          he无
          
          //从字符源数组value的offset索引位置处连续取出count长度的的子数组构建字符串
          char [] chars = new char[3];
          chars[0] = 'h';
          chars[1] = 'e';
          chars[2] = '无';
          String str = new String(chars, 1, 2);
          Log.d("字符串", str);
          
          //输出:
          e无
    
  • 小结

    • java字符串用双引号""(String),字符用单引号''(char)
    • 字符串String是由字符char作为单元构成的,char作为java中字符串的基本单元code unit

通过unicode points代码点

  • 方法

          /*
           * codePoints - 作为 Unicode 代码点的源的数组。
               offset - 初始偏移量。
               count - 长度。
           */
          //从Unicode代码点的源的数组codePoints的offset索引位置处连续取出count长度的的子数组构建字符串
          //如果 offset 和 count 参数索引字符超出 value 数组的范围,则会抛出异常 IndexOutOfBoundsException
          //如果在 codePoints 中发现任何无效的 Unicode 代码点,则会抛出异常 IllegalArgumentException
          public String(int[] codePoints,
                        int offset,
                        int count)
    
  • 例子

          int[] points = new int[2];
          points[0] = 104;
          points[1] = 101;
          String str = new String(points, 0, 2);
          Log.d("字符串", str);
          
          //输出:
          he
    
  • 小结

    • codePoints是字符串单元对应的十进制数字,104对应h101对应e
    • code point先转换为字符charchar再转化为字符串String,即code point —> char —> String

通过字符集 bytes Charset

  • 方法

          //从字节源数组bytes的offset索引位置处开始,截取length长度的子数组,并将子数组按照响应的解码方法解码,构建字符串
          // - 如果指定的字符集不受支持 ,抛出异常UnsupportedEncodingException
          // - 如果 offset 和 length 参数索引字符超出 bytes 数组的范围 , 抛出异常IndexOutOfBoundsException
          
          /**
           *  bytes - 要解码为字符的 byte 
              offset - 要解码的第一个 byte 的索引 
              length - 要解码的 byte 数 
              charsetName - 受支持 charset 的名称
           */
          public String(byte[] bytes,
                        int offset,
                        int length,
                        String charsetName)
                 throws UnsupportedEncodingException
          
          /**
           *  bytes - 要解码为字符的 byte 
              offset - 要解码的第一个 byte 的索引 
              length - 要解码的 byte 数 
              charset - 用来解码 bytes 的 charset
           */
          public String(byte[] bytes,
                        int offset,
                        int length,
                        Charset charset)
          
          /**
           *  bytes - 要解码为字符的 byte 
              charsetName - 受支持的 charset 的名称
           */
          public String(byte[] bytes,
                        String charsetName)
                 throws UnsupportedEncodingException
          
          /**
           *  bytes - 要解码为字符的 byte 
              charset - 要用来解码 bytes 的 charset
           */
          public String(byte[] bytes,
                        Charset charset)
          
          /**
           *  bytes - 要解码为字符的 byte 
              offset - 要解码的第一个 byte 的索引 
              length - 要解码的 byte 数
           */
          public String(byte[] bytes,
                        int offset,
                        int length)
          
          /**
           *  bytes - 要解码为字符的 byte
           */
          public String(byte[] bytes)
    
  • 例子

          String string = "hello 世界 world";
          byte[] bytes = string.getBytes(); //默认是UTF-8编码
          
          String str = new String(bytes);
          Log.d("字符串", str);
          String UTF8Str = new String(bytes, Charset.forName("UTF-8"));
          Log.d("字符串", UTF8Str);
          try {
                  String gbkStr = new String(bytes, "GBK");
                  Log.d("字符串", gbkStr);
          } catch (UnsupportedEncodingException e) {
                  Log.d("字符串", "error-----");
          }
          
          String strOffset = new String(bytes, 1, 2);
          String UTF8StrOffset = new String(bytes, 1, 2, Charset.forName("UTF-8"));
          String gbkStrOffset = new String(bytes, 1, 2, Charset.forName("GBK"));
          
          Log.d("字符串", strOffset);
          Log.d("字符串", UTF8StrOffset);
          Log.d("字符串", gbkStrOffset);
          
          //输出:
          hello 世界 world
          hello 世界 world
          hello 涓栫晫 world
          el
          el
          el
    
  • 小结

    • 通过使用指定的字符集 解码指定的byte 子数组,构造一个新的 String
    • 编码方式和解码方式不一致时,会导致显示异常,有可能会出现乱码,如UTF-8编码,GBK解码

JS String.from

通过UTF-16 code units

  • 方法

          //有序的UTF-16 code units编码单元构建,有效范围时是0 and 65535,超过范围的会被截断,舍弃
          String.fromCharCode(num1[, ...[, numN]])
    
  • 例子

          console.log(String.fromCharCode(65, 66, 67))
          console.log(String.fromCharCode(0x2014))
          console.log(String.fromCharCode(0x12014))
          console.log(String.fromCharCode(8212))
          console.log(String.fromCharCode(65, 66, 67, 0x2014))
          
          //输出:
          ABC
          —
          —
          —
          ABC—
    
  • 小结

    • 可以直接使用UTF-16 code units 对应的十进制数字,(65, 66, 67)
    • 可以直接使用UTF-16 code units 对应的十六进制数字,十六进制0x2014对应十进制为8212,输出结果都为:
    • 也可以组合使用,只要填入的内容可以转化为数字,并且在0~65535范围内就行
    • 因为使用的是162进制,即416进制,所以范围为0~65535

通过code points

  • 方法

          //有序的code points
          String.fromCodePoint(num1[, ...[, numN]])
    
  • 例子

          console.log(String.fromCodePoint(42))
          console.log(String.fromCodePoint(65, 90))
          console.log(String.fromCodePoint(0x404))
          console.log(String.fromCodePoint(1028))
          console.log(String.fromCodePoint(0x2F804))
          console.log(String.fromCodePoint(194564))
          
          //输出:
          *
          AZ
          Є
          Є
          ?
          ?
    
  • 小结

    • 通过code point构建字符串,没有范围0~65535的限制
    • 通过code point构建字符串,可以使用16进制,也可以使用10进制,如?的16进制0x404转化为10进制为1028,输出结果都为Є16进制0x2F804转化为10进制为194564,输出结果都为?,但是不可以使用字符常量,如'+',会报错

小结

不同点

  • oc中字符串写法@""java中字符串写法""js中字符串写法""''都可以,一个字符@的区别
  • char基本数据类型,oc中表示1个字节、java表示2个字节
  • bytejava中表示个字节,oc也是个字节,ocByte
  • unicode编码需要用2个字节表示,oc中用unichar表示,javachar
  • java字符串的构建关系:code point —> char —> String

相同点

  • 通过字符串常量初始化的时候,推荐直接赋值

          [//oc](//oc)
          NSString *str = @"one";
          
          //java
          String str = "hello";
          
          //js
          var str = "hello world"
    
  • code point —> code unit —> string

  • 字符串的长度范围等处理都是都以unicode unit为基础的,即组成该字符串所需要的unicode unit数目,即需要多少了2字节存储,ocunicharjavachar

          //oc
          NSString *string = @"hello 世界 world";
          NSLog(@"%ld", string.length);
          //输出:
          14
          
          
          //java
          String string = "hello 世界 world";
          Log.d("字符串", String.valueOf(string.length()));
          //输出:
          14
          
          
          //js
          var str = "hello 世界 world";
          console.log(str.length)
          //输出:
          14
    
  • 字符串常量

            //oc
            NSString *str = @"one";
            
            //java
            String str = "hello";
            
            //js
            var str = "hello 世界 world";
    
  • 把字符串源(字节bytes,字符charunicode units)按照指定的编码方式进行解码,
    - javacharbytesunicode points
    - occharactersbytesNSDataCStringNSURLfile
    - js: CharCodeCodePoint

  • 通过 unicode 字符构建字符串

    • oc : initWithCharacters ,可以使用 十六进制(如0x2b)十进制数字(如43)字符常量(如'+')

          // 43 、0x2b 、'+' 这些输出的都是 + 
          const unichar ch = 43;
          NSString *str = [[NSString alloc] initWithCharacters:&ch length:3];
          NSLog(@"%@", str);
          //输出:
          +
          
          unichar ch[3];
          ch[0] = '+';
          ch[1] = 43;
          ch[2] = 0x2b;
          NSString *str = [[NSString alloc] initWithCharacters:ch length:sizeof(ch) / sizeof(unichar)];
          NSLog(@"%@", str);
          //输出:
          +++
      
    • java : public String(char[] value)public String(int[] codePoints, int offset, int count) ,可以使用 十六进制(如0x2b)十进制数字(如43)字符常量(如'+')

          char [] chars = new char[3];
          chars[0] = '+';
          chars[1] = 43;
          chars[2] = 0x2b;
          
          String str = new String(chars);
          Log.e("字符串", str);
          // 输出:
          E/字符串: +++
          
          
          int[] points = new int[3];
          points[0] = '+';
          points[1] = 43;
          points[2] = 0x2b;
          
          String str = new String(points, 0, 3);
          Log.e("字符串", str);
          // 输出:
          E/字符串: +++
      
    • js : String.fromCodePointString.fromCharCode ,可以使用 十六进制(0x2b)十进制数字(如43)不可以使用字符常量(如'+')String.fromCodePoint会报错(RangeError: Invalid code point NaN),String.fromCharCode会输出空字符

          console.log(String.fromCodePoint(0x2b));
          console.log(String.fromCodePoint(43));
              // console.log(String.fromCodePoint('+')); // 会抛出异常 RangeError: Invalid code point NaN
          console.log(String.fromCharCode('+')); //
          
          console.log("-------");
          //输出:
          +
          +
          
          -------
      

二、长度 length

  • OC length

    length

    NSString *str = @"one";
    NSLog(@"%ld", str.length);
    //输出:3
    
  • Java length()

    length()

    String str = "one";
    Log.d("length", String.valueOf(str.length()));
    //输出:3
    
  • JS length

    length

    var str = "one";
    console.log(str.length)
    //输出:3
    
  • 小结

    关键字都是 length

三、比较 compare

基本概念

  1. 字典排序: 按字典顺序比较两个字符串。该比较基于字符串中各个字符的 Unicode 值。按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此 String 对象位于参数字符串之,则比较结果为一个负整数。如果按字典顺序此 String 对象位于参数字符串之,则比较结果为一个正整数。如果这两个字符串相等,则结果为 0

OC equalcompare

  • 方法

        //相等判断
        - (BOOL)isEqualToString:(NSString *)aString;
        //按照unicode编码顺序比较、相等:NSOrderedSame,在前面NSOrderedAscending,在后面NSOrderedDescending
        - (NSComparisonResult)compare:(NSString *)string;
        //忽略大小写进行比较、'A'和'a'相等
        - (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
        //比较大小,根据传入的mask参数
        - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
        //截取调用者range范围的子字符串和参数string进行比较
        - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare;
        //本地化的处理 @
        - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare locale:(nullable id)locale;
        - (NSComparisonResult)localizedCompare:(NSString *)string;
        - (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;
        - (NSComparisonResult)localizedStandardCompare:(NSString *)string API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
        
        //比较结果如下:
        typedef NS_ENUM(NSInteger, NSComparisonResult) {
              NSOrderedAscending = -1L,
              NSOrderedSame, 
              NSOrderedDescending
        };
        
        //mask选项如下:
        /* These options apply to the various search/find and comparison methods (except where noted).
        */
        typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) {
            NSCaseInsensitiveSearch = 1,
            NSLiteralSearch = 2,      /* Exact character-by-character equivalence */
            NSBackwardsSearch = 4,        /* Search from end of source string */
            NSAnchoredSearch = 8,     /* Search is limited to start (or end, if NSBackwardsSearch) of source string */
            NSNumericSearch = 64,     /* Added in 10.2; Numbers within strings are compared using numeric value, that is, Foo2.txt < Foo7.txt < Foo25.txt; only applies to compare methods, not find */
            NSDiacriticInsensitiveSearch API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 128, /* If specified, ignores diacritics (o-umlaut == o) */
            NSWidthInsensitiveSearch API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 256, /* If specified, ignores width differences ('a' == UFF41) */
            NSForcedOrderingSearch API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 512, /* If specified, comparisons are forced to return either NSOrderedAscending or NSOrderedDescending if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with NSCaseInsensitiveSearch specified) */
            NSRegularExpressionSearch API_AVAILABLE(macos(10.7), ios(3.2), watchos(2.0), tvos(9.0)) = 1024    /* Applies to rangeOfString:..., stringByReplacingOccurrencesOfString:..., and replaceOccurrencesOfString:... methods only; the search string is treated as an ICU-compatible regular expression; if set, no other options can apply except NSCaseInsensitiveSearch and NSAnchoredSearch */
        };
    
  • 例子

        NSString *str1 = @"A";
        NSString *str2 = @"a";
        NSComparisonResult result = [str1 compare:str2];
        if (result == NSOrderedSame) {
            NSLog(@"比较:相等");
        } else if (result == NSOrderedAscending) {
            NSLog(@"比较:位于前面");
        } else {
            NSLog(@"比较:位于后面");
        }
        //打印结果:
        比较:位于前面
        
        
        NSString *str1 = @"aA";
        NSString *str2 = @"a";
        NSComparisonResult result = [str1 compare:str2];
        if (result == NSOrderedSame) {
            NSLog(@"比较:相等");
        } else if (result == NSOrderedAscending) {
            NSLog(@"比较:位于前面");
        } else {
            NSLog(@"比较:位于后面");
        }
        //输出:
        比较:位于后面
    
  • 小结
    - 根据mask传入的参数不同,获取的结果不一样;如mask传入NSCaseInsensitiveSearch,等价于caseInsensitiveCompare:
    - 比较只返回比较结果,不会返回差值

Java equalcompare

  • 方法

        //字典顺序比较大小
        public int compareTo(String anotherString)
        //忽略大小写进行比较
        public int compareToIgnoreCase(String str)
        
        //相等判断,类型也要相同,为String类
        public boolean equals(Object anObject) {  }
        //相等判断,忽略大小写,'A'和'a'相等
        public boolean equalsIgnoreCase(String anotherString) { }
        //相等判断,内容相等,类型可能不相同
        public boolean contentEquals(StringBuffer sb) { }
        public boolean contentEquals(CharSequence cs) { }
    
  • 例子

        //相同长度,某个位置处字符不同
        String str1 = "A";
        String str2 = "a";
        int result = str1.compareTo(str2);
        Log.d("差值:", String.valueOf(result));
        if (result == 0) {
              Log.d("排序:", "相等");
        } else if (result < 0) {
              Log.d("排序:", "位于前面");
        } else {
              Log.d("排序:", "位于后面");
        }
        //输出:
        -32
        位于前面
        
        
        //长度不同的比较
        String str1 = "aA";
        String str2 = "a";
        int result = str1.compareTo(str2);
        Log.d("差值:", String.valueOf(result));
        if (result == 0) {
              Log.d("排序:", "相等");
        } else if (result < 0) {
              Log.d("排序:", "位于前面");
        } else {
              Log.d("排序:", "位于后面");
        }
        //输出:
        1
        位于后面
        
        //索引位置处字符不同,长度不同
        String str1 = "Aa";
        String str2 = "a";
        int result = str1.compareTo(str2);
        Log.d("差值:", String.valueOf(result));
        if (result == 0) {
              Log.d("排序:", "相等");
        } else if (result < 0) {
              Log.d("排序:", "位于前面");
        } else {
            Log.d("排序:", "位于后面");
        }
        //输出:
        -32
        位于前面
        
        
        //忽略大小写的比较
        String str1 = "A";
        String str2 = "a";
        int result = str1.compareToIgnoreCase(str2);
        Log.d("差值:", String.valueOf(result));
        if (result == 0) {
              Log.d("排序:", "相等");
        } else if (result < 0) {
              Log.d("排序:", "位于前面");
        } else {
              Log.d("排序:", "位于后面");
        }
        //输出:
        0
        相等
    
  • 小结
    - 字符串不同的情况:1、相同索引处的unicode units不同2、长度不同;3、1和2都有
    - 比较的优先级:优先比较1的情况,然后在比较2的情况
    - 对于1的情况,返回的unicode units差值this.charAt(k)-anotherString.charAt(k)
    - 对于2的情况,返回的是长度差值this.length()-anotherString.length()

JS compare

  • 方法

        /**
          referenceStr在compareString“前面”,返回“负值”,不一定是-1,不同浏览器返回“负值”不同,但是都是“负值”
          referenceStr在compareString“后面”,返回“正值”,不一定是1,不同浏览器返回“正值”不同,但是都是“正值”
          referenceStr在compareString“相同位置”,返回0
         */
        referenceStr.localeCompare(compareString[, locales[, options]])
    
  • 例子

        //字符不同
        var str1 = "A"
        var str2 = "Z"
        var result = str1.localeCompare(str2)
        console.log(result)
        if (result == 0) {
              console.log("比较:", "相等");
        } else if (result < 0) {
              console.log("比较:", "位于前面");
        } else {
              console.log("比较:", "位于后面");
        }
        
        //输出:
        -1
        比较: 位于前面
        
        
        //长度不同
        var str1 = "AZ"
        var str2 = "A"
        var result = str1.localeCompare(str2)
        console.log(result)
        if (result == 0) {
          console.log("比较:", "相等");
        } else if (result < 0) {
          console.log("比较:", "位于前面");
        } else {
          console.log("比较:", "位于后面");
        }
        //输出:
        1
        位于后面
    
  • 小结
    - 比较只返回比较结果,不会返回差值

小结

  • 相同点
    - 小于:返回负值
    - 相等:返回0
    - 大于:返回正值

  • 不同点
    - jsoc只是单纯进行字符串比较,不会返回差值;但是java会返回差值(见?);oc对比较结果进行了封装,是一个枚举类型:

          typedef NS_ENUM(NSInteger, NSComparisonResult) {
                  NSOrderedAscending = -1L,
                  NSOrderedSame, 
                  NSOrderedDescending
          };
    
    - `oc`和`java`提供了`忽略大小写`的比较方法,`js`没有直接方法,但是可以先全部转为`小写字母`(`toLowerCase()`),然后再进行`比较`(`localeCompare()`);
    

四、前缀/后缀 hasPrefixhasSuffixstartsWithendsWith

OC hasPrefixhasSuffix

  • 方法

        // 前缀
        - (BOOL)hasPrefix:(NSString *)str;
        // 后缀
        - (BOOL)hasSuffix:(NSString *)str;
        // 获取相同的前缀
        - (NSString *)commonPrefixWithString:(NSString *)str options:(NSStringCompareOptions)mask;
    
  • 例子

        NSString *str = @"hello world";
        if ([str hasPrefix:@"hello"]) {
            NSLog(@"包含前缀:hello");
        } else {
            NSLog(@"不包含前缀:hello");
        }
        
        if ([str hasPrefix:@"world"]) {
            NSLog(@"包含前缀:world");
        } else {
            NSLog(@"不包含前缀:world");
        }
        
        if ([str hasSuffix:@"hello"]) {
            NSLog(@"包含后缀:hello");
        } else {
            NSLog(@"不包含后缀:hello");
        }
        
        if ([str hasSuffix:@"world"]) {
            NSLog(@"包含后缀:world");
        } else {
            NSLog(@"不包含后缀:world");
        }
        
        // 输出:
        包含前缀:hello
        不包含前缀:world
        不包含后缀:hello
        包含后缀:world
        
        NSString *str = @"onetwothreeonetwo";
        NSString *searchStr = @"oneuoptwo";
        NSString *commonPrefix = [str commonPrefixWithString:searchStr options:0];
        NSLog(@"%@", commonPrefix);
        
        // 输出:
        one
    
  • 小结

Java startsWithendsWith

  • 方法

        // 前缀
        public boolean startsWith(String prefix)
        // 如果参数表示的字符序列是此对象从索引 toffset 处开始的子字符串前缀,则返回 true;否则返回 false。如果 toffset 为负或大于此 String 对象的长度,则结果为 false;否则结果与以下表达式的结果相同:
        public boolean startsWith(String prefix, int toffset)
        
        //后缀
        public boolean endsWith(String suffix)
    
  • 例子

        String str = "hello world";
        if (str.startsWith("hello")) {
            Log.e("前缀判断", "包含前缀:hello");
        } else {
            Log.e("前缀判断", "不包含前缀:hello");
        }
        
        if (str.startsWith("world")) {
            Log.e("前缀判断", "包含前缀:world");
        } else {
            Log.e("前缀判断", "不包含前缀:world");
        }
        
        if (str.endsWith("hello")) {
            Log.e("后缀判断", "包含后缀:hello");
        } else {
            Log.e("后缀判断", "不包含后缀:hello");
        }
        
        if (str.endsWith("world")) {
            Log.e("后缀判断", "包含后缀:world");
        } else {
            Log.e("后缀判断", "不包含后缀:world");
        }
        
        // 输出:
        E/前缀判断: 包含前缀:hello
        E/前缀判断: 不包含前缀:world
        E/后缀判断: 不包含后缀:hello
        E/后缀判断: 包含后缀:world
    
  • 小结

JS startsWithendsWith

  • 方法

        /**
         * “源字符串”的 position 位置(包含)之后的子字符串 是否是以 searchString 开头的
         * 1、position 表示在 源字符串str 中搜索 searchString 的 “开始位置”,默认值为 0,也就是真正的字符串开头处
         */
        str.startsWith(searchString [, position]);
        
        /**
         * “源字符串”的 position 位置(不包含)之后的子字符串 是否是以 searchString 结尾的
         * 1、position 表示在 源字符串str 中搜索 searchString 的结束位置,默认值为 str.length,也就是真正的字符串结尾处。
         */
        str.endsWith(searchString [, position]);
    
  • 例子

        //前缀
        var str = 'hello world';
        console.log(str.startsWith('hello'));
        console.log(str.startsWith('hello', 5));
        console.log(str.startsWith('world'));
        console.log(str.startsWith('world', 6));
        console.log(str.startsWith('hello', 20));
        
        //输出:
        true
        false
        false
        true
        false
        
        
        //后缀
        var str = 'hello world';
        console.log(str.endsWith('world'));
        console.log(str.endsWith('world', 5));
        console.log(str.endsWith('hello'));
        console.log(str.endsWith('hello', 4));
        console.log(str.endsWith('hello', 5));
        console.log(str.endsWith('hello', 6));
        
        //输出:
        true
        false
        false
        false
        true
        false
    
  • 小结
    - startsWith 前缀判断,“源字符串” position (包含) 到 length - 1 范围内的字符串是不是以 searchString 开头的
    - endsWith 后缀判断,“源字符串” 0position (不包含) 范围内的字符串是不是以 searchString 结尾的
    - 先从 “源字符串” 获取判断的字符串范围,然后再进行判断

小结

  • JavaJS 的关键字为 startsWithendsWithOChasPrefixhasSuffix

五、包含 containsincludes

OC contains

  • 方法

        //包含
        - (BOOL)containsString:(NSString *)str API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
        - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)str API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
        
        - (BOOL)localizedStandardContainsString:(NSString *)str API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
        - (NSRange)localizedStandardRangeOfString:(NSString *)str API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
    
  • 例子

        NSString *str = @"oneTwo";
        NSString *searchStr = @"ONE";
        BOOL result = [str containsString:searchStr];
        BOOL result2 = [str localizedCaseInsensitiveContainsString:searchStr];
        NSLog(@"%@", @(result));
        NSLog(@"%@", @(result2));
        
        // 输出: 0 为 NO,1为YES
        0
        1
    
  • 小结

Java contains

  • 方法

        public boolean contains(CharSequence s)
    
  • 例子

        String str = "hello world";
        boolean result = str.contains("hello");
        boolean result2 = str.contains("me");
        Log.e("包含", String.valueOf(result));
        Log.e("包含", String.valueOf(result2));
        
        // 输出:
        E/包含: true
        E/包含: false
    
  • 小结

JS includes

  • 方法

        /*
         * 判断一个字符串是否包含在另一个字符串中,根据情况返回true或false。
         */
        str.includes(searchString[, position])
    
  • 例子

        var str = 'hello world';
        var result = str.includes('hello');
        var result2 = str.includes('me');
        console.log(result);
        console.log(result2);
        
        //输出:
        true
        false
    
  • 小结

六、拼接/插入 appendinsertconcat

基本概念

  • oc中的字符串类
  • NSString: 不可变的
  • NSMutableString:可变的
  • Java的字符串类:
  • String: 不可变;
  • StringBuilder:可变的,线程不安全
  • StringBuffer:可变的,线程安全
  • 小结:StringBuilderStringBuffer快,优先使用StringBuilder

OC appendinsertpadding

  • 方法

        //不可变字符串的处理-----------
        //把字符串aString拼接“源字符串”的"末尾"
        - (NSString *)stringByAppendingString:(NSString *)aString;
        //把字符串aString拼接“源字符串”的"末尾",带有格式的拼接
        - (NSString *)stringByAppendingFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
        
        //在“源字符串”的末尾位置处拼接字符串“padString”,从使padString的padIndex所有位置处开始拼接,使“源字符串”的长度为newLength
        /*
         * newLength : 源字符串需要扩展到的长度
                                   大于原来长度,末尾插入
                                   等于原来长度,不做处理
                                   小于原来长度,截取处理
           padString : 需要拼接的子字符串
           padIndex : 需要拼接的子字符串padString开始拼接的位置(仅仅是第一次),超过范围会crash
         */
        - (NSString *)stringByPaddingToLength:(NSUInteger)newLength withString:(NSString *)padString startingAtIndex:(NSUInteger)padIndex;
        
        //可变字符串的处理-----------
        //源字符串“末尾”拼接字符串aString
        - (void)appendString:(NSString *)aString;
        //源字符串“末尾”按照格式拼接字符串
        - (void)appendFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
        //源字符串loc位置处插入字符串aString
        - (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
    
  • 例子

        NSString *str = @"one";
        NSString *str2 = [str stringByAppendingString:@"two"];
        NSString *str3 = [str stringByAppendingFormat:@"%@ hello %d", str2, 3];
        NSLog(@"%@", str2);
        NSLog(@"%@", str3);
        
        //输出:
        onetwo
        oneonetwo hello 3
        
        
        NSString *str = @"one";
        NSString *result = [str stringByPaddingToLength:10 withString:@"+" startingAtIndex:0];
        NSLog(@"%@", result);
        NSLog(@"%ld", result.length);
        //输出:
        str      length        string        index        result        result.length
        one      10            +             0            one+++++++    10
        one      3             +             0            one           3
        one      2             +             0            on            2
        one      0             +             0                          0
        one      0             +             1                crash了        
        one      6             +-            1            one-+-        6
        
        
        
        NSMutableString *str = [NSMutableString string];
        NSLog(@"%@", str);
        [str appendString:@"two"];
        NSLog(@"%@", str);
        [str appendFormat:@"hello %d", 3];
        NSLog(@"%@", str);
        [str insertString:@"first " atIndex:0];
        NSLog(@"%@", str);
        //输出:
         
        two
        twohello 3
        first twohello 3
    
  • 小结
    - NSString不会改变原来字符串的值,会返回一个新的值
    - NSMutableString是对原来字符串进行处理,不会返回新值

Java concatformatappendinsert

  • 方法

        //将指定字符串str拼接到“源字符串”的结尾
        public String concat(String str)
        
        //类方法,格式化拼接字符串
        public static String format(String format,
                                    Object... args)
        
        //类方法,格式化拼接字符串,本地化的
        public static String format(Locale l,
                                    String format,
                                    Object... args)
        
        //append -----
        public StringBuilder append(Object obj)
        public StringBuilder append(String str)
        public StringBuilder append(StringBuffer sb)
        public StringBuilder append(CharSequence s)
        public StringBuilder append(CharSequence s, int start, int end)
        public StringBuilder append(char[] str)
        public StringBuilder append(char[] str, int offset, int len)
        public StringBuilder append(boolean b)
        public StringBuilder append(char c)
        public StringBuilder append(int i)
        public StringBuilder append(long lng)
        public StringBuilder append(float f)
        public StringBuilder append(double d)
        public StringBuilder appendCodePoint(int codePoint)
        
        //insert
        public StringBuilder insert(int offset, boolean b)
        public StringBuilder insert(int offset, char c)
        public StringBuilder insert(int offset, int i)
        public StringBuilder insert(int offset, long l)
        public StringBuilder insert(int offset, float f)
        public StringBuilder insert(int offset, double d)
    
  • 例子

        String str = "one";
        String result = str.concat("two");
        Log.d("字符串拼接", result);
        //输出:
        onetwo
        
        String str = "one";
        String result = String.format("%s %s %d", str, "two", 10);
        Log.d("字符串拼接", result);
        //输出:
        one two 10
        
        
        [//append---](//append---)
        StringBuilder sb = new StringBuilder();
        Log.d("字符串拼接:开始:", sb.toString());
        
        sb.append("str");
        Log.d("字符串拼接:拼接string之后:", sb.toString());
        
        String nullStr = null;
        sb.append(" ");
        sb.append(nullStr);
        Log.d("字符串拼接:拼接空string之后:", sb.toString());
        
        StringBuilder sb2 = new StringBuilder("sb");
        sb.append(" ");
        sb.append(sb2);
        Log.d("拼接StringBuilder之后:", sb.toString());
        
        StringBuffer sf = new StringBuffer("sf");
        sb.append(" ");
        sb.append(sf);
        Log.d("拼接StringBuffer之后:", sb.toString());
        
        char[] chars = new char[2];
        chars[0] = 'a';
        chars[1] = 'b';
        sb.append(" ");
        sb.append(chars);
        Log.d("拼接char[]之后:", sb.toString());
        
        sb.append(" ");
        sb.append(true);
        Log.d("字符串拼接:拼接boolean之后:", sb.toString());
        
        sb.append(" ");
        sb.append('a');
        Log.d("字符串拼接:拼接char之后:", sb.toString());
        
        sb.append(" ");
        sb.append(10);
        Log.d("字符串拼接:拼接int之后:", sb.toString());
        
        sb.append(" ");
        sb.append(100L);
        Log.d("字符串拼接:拼接long之后:", sb.toString());
        
        sb.append(" ");
        sb.append(20.32f);
        Log.d("字符串拼接:拼接float之后:", sb.toString());
        
        sb.append(" ");
        sb.append(50.5);
        Log.d("字符串拼接:拼接double之后:", sb.toString());
        
        sb.append(" ");
        sb.appendCodePoint(104);
        Log.d("字符串拼接:拼接codePoint之后:", sb.toString());
        
        //最终输出:
        str null sb sf ab true a 10 100 20.32 50.5 h
        
        
        //insert---  参考`append`
    
  • 小结
    - appendinsert可以看出是format的便捷方法
    - 如果拼接的值为null,则向该序列中追加 4 个 "null" 字符
    - String类拼接用concatStringBuilder类和StringBuffer类用appendinsert

JS +concatrepeat

  • 方法

        /**
         * 使用加号 + 进行拼接
         */
        +
        
        /**
         * 把 “源字符串” 重复 count 次 得到新的字符串
         * 1、count 范围为 [0, +∞),超过范围会抛出异常 RangeError;count 为 0 返回空字符串 ''
         */
        str.repeat(count)
        
        /**
         * 在 “源字符串”的基础上拼接 字符串 string2 、 string3 、 ... stringN
         */
        str.concat(string2, string3[, ..., stringN])
    
  • 例子

        var str = "";
        str += "one";
        console.log(str)
        //输出:
        one
        
        //重复次数
        var str = 'hello';
        var result = str.repeat(2);
        var result2 = str.repeat(0);
        // var result3 = str.repeat(-1);
        
        console.log(result);
        console.log(result2);
        // console.log(result3);
        console.log("++++++++")
        
        //输出:
        hellohello
        
        ++++++++
        
        
        var str = 'hello';
        var result = str.concat(' ', 'world');
        console.log(result);
        
        //输出:
        hello world
    
  • 小结
    - js的字符串拼接使用加号+即可
    - repeat(count)count 的范围为 [0, +∞) ,超过范围会抛出异常,count 等于 0 返回空字符串 ''

小结

  • 相同点
    1. ocjava方法的关键字为 appendinsert,java多了concat
    1. ocjava都可以通过格式化字符串format来拼接字符串
  • 不同点
    1. jsjava都可以使用加号+拼接字符串,oc不可以

七、删除 delete

OC delete

  • 方法

        //删除“源字符串”range范围的字符
        - (void)deleteCharactersInRange:(NSRange)range;
    
  • 例子

        NSMutableString *str = [NSMutableString stringWithString:@"hello"];
        [str deleteCharactersInRange:NSMakeRange(1, 2)];
        NSLog(@"%@", str);
        //输出:
        hlo
    
  • 小结
    - NSMutableString类才有删除方法
    - 范围range超过源字符串范围时,会crash

Java delete

  • 方法

        //删除start(包含)到end(不包含)范围内的字符
        [//end可以>=length,超过length表示一直删除到字符串尾部](//end可以>=length,超过length表示一直删除到字符串尾部)
        //如果 start 为负、大于 length() 或大于 end,会抛出异常StringIndexOutOfBoundsException
        public StringBuilder delete(int start, int end)
        
        //删除index位置处的字符,此序列将缩短一个 char。
        //注:如果给定索引处的字符是增补字符,则此方法将不会移除整个字符。如果需要准确处理增补字符,那么可以通过调用 Character.charCount(thisSequence.codePointAt(index))(用此序列取代 thisSequence)来确定要移除的 char 数。
        public StringBuilder deleteCharAt(int index)
    
  • 例子

        StringBuilder sb = new StringBuilder("hello");
        sb.delete(1, 3); //删除el
        Log.d("字符串删除:", sb.toString());
        //输出:
        hlo
        
        StringBuilder sb = new StringBuilder("hello");
        sb.delete(1, 10); //删除ello
        Log.d("字符串删除:", sb.toString());
        //输出:
        h
        
        //删除某个位置的字符
        StringBuilder sb = new StringBuilder("hello");
        sb.deleteCharAt(1);
        Log.d("字符串删除:", sb.toString());
        //输出:
        hllo
    
  • 小结
    - deletedeleteCharAtStringBuilder类和StringBuffer类才有的
    - end可以大于等于字符串length,大于等于length会一直删除掉“源字符串”的末尾
    - 如果 start 为负、大于 length() 或大于 end,会抛出异常StringIndexOutOfBoundsException
    - deleteCharAt,准确删除的话需要调用Character.charCount(thisSequence.codePointAt(index)),确定删除的字符数

JS

  • 参考 替换

小结

  • 相同点
    1. 对于含有emoji字符的字符串,有可能需要3个字节才能表示,但是unicode unit为2个字节,这时候使用常规的处理会出现问题,需要准确的判断字符串:

          [//oc:](//oc:)
          - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
          - (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
          
          //java:
          `Character.charCount(thisSequence.codePointAt(index))`
    
  • 不同点

八、获取 charcodePointAt

OC characterAtIndex

  • 方法

        /**
         * 获取 index 位置处的 unicode unit 的数字表示形式
         * 1、index 超过范围 [0, length - 1) 会crash ,因为范围越界了
         */
        - (unichar)characterAtIndex:(NSUInteger)index;
    
  • 例子

        NSString *str = @"hello world!";
        unichar ch = [str characterAtIndex:1];
        NSLog(@"%d -- %@", ch, [[NSString alloc] initWithCharacters:&ch length:1]);
        //输出:
        101 -- e
        
        //当 index 为 20 时,crash 了,
        Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFConstantString characterAtIndex:]: Range or index out of bounds'
    
  • 小结

Java charAtcodePointAt

  • 方法

        // 返回指定索引处的 char 值。索引范围为从 0 到 length() - 1。序列的第一个 char 值位于索引 0 处,第二个位于索引 1 处,依此类推,这类似于数组索引;如果 index 参数为负或小于此字符串的长度,会抛出异常
        public char charAt(int index)
        // 返回指定索引处的字符(Unicode 代码点)。索引引用 char 值(Unicode 代码单元),其范围从 0 到 length() - 1
        public int codePointAt(int index)
    
  • 例子

        String str = "hello world!";
        char ch = str.charAt(1);
        Log.e("获取", String.valueOf(ch));
        
        // 输出:
        E/获取: e
        
        
        String str = "hello world!";
        int point = str.codePointAt(1);
        Log.e("获取", String.valueOf(point));
        // 输出:
        E/获取: 101
    
  • 小结

JS charAtcharCodeAtcodePointAt

  • 方法

        /**
         * 获取index位置处的 UTF-16 code unit 的字符串形式
         * 1、不填写参数,默认获取 0 位置处的字符
         * 2、index 超过 “源字符串” 的范围,返回空字符串 ""
         */
        character = str.charAt(index)
        
        /**
         * 获取 index 处 UTF-16 code unit 的 code point 所代表的数字
         * 1、index 超过范围 返回 NaN
         */
        str.charCodeAt(index)
        
        /**
         * 获取 index 位置处的 UTF-16 code unit 的 code point 的数字形式
         * 1、如果 index 超过字符串的范围,返回undefined
         */
        str.codePointAt(pos)
    
  • 例子

        var str = "hello world"
        var character = str.charAt()
        var character1 = str.charAt(0)
        var character2 = str.charAt(20)
        
        console.log(character)
        console.log(character1)
        console.log(character2)
        console.log("-----")
        
        //输出:
        h
        h
        
        -----
        
        
        
        var str = "hello world"
        var result = str.charCodeAt(0)
        var result1 = str.charCodeAt(20)
        
        console.log(result)
        console.log(result1)
        
        //输出:
        104
        NaN
        
        
        var str = "hello world"
        var result = str.codePointAt(0)
        var result1 = str.codePointAt(20)
        
        console.log(result)
        console.log(result1)
        
        //输出:
        104
        undefined
    
  • 小结

小结

  • 可以获取到 index 位置的字符 、代码点 code point

九、查找 rangeindexOflastIndexOfsearch

OC range

  • 方法

        // 查找给定的字符串 ------- 
        // “源字符串” 全部范围内查找
        - (NSRange)rangeOfString:(NSString *)searchString;
        // “源字符串” 全部范围内查找,添加一些条件
        - (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask;
        // “源字符串” rangeOfReceiverToSearch 范围内查找 ,范围超过 字符串 长度会crash
        - (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch;
        // 本地化的查找
        - (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch locale:(nullable NSLocale *)locale API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        
        // 查找给定的字符集合 -------
        - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet;
        - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet options:(NSStringCompareOptions)mask;
        - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch;
    
  • 例子

        NSString *str = @"hello world";
        NSLog(@"%@", NSStringFromRange([str rangeOfString:@"hello"]));
        NSLog(@"%@", NSStringFromRange([str rangeOfString:@"me"]));
        
        // 输出:
        {0, 5}
        {9223372036854775807, 0}
        
        
        NSString *str = @"hello world";
        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"l"];
        NSLog(@"%@", NSStringFromRange([str rangeOfCharacterFromSet:set]));
        // 输出:
        {2, 1}
    
  • 小结
    - 如果查找到返回查找到的范围,没有查找到话 rangelength == 0

Java indexOflastIndexOf

  • 方法

        // 在”源字符串“中查找 字符串str 或者 ch代表的Unicode 代码点代表的字符 ”第一次“ 出现的位置,如果未出现该字符,则返回 -1
        public int indexOf(String str)
        public int indexOf(String str, int fromIndex)
        public int indexOf(int ch)
        public int indexOf(int ch, int fromIndex)
        
        // 在”源字符串“中查找 字符串str 或者 ch代表的Unicode 代码点代表的字符 ”最后一次“ 出现的位置,如果未出现该字符,则返回 -1
        public int lastIndexOf(String str)
        public int lastIndexOf(String str, int fromIndex)
        public int lastIndexOf(int ch)
        public int lastIndexOf(int ch, int fromIndex)
    
  • 例子

        String str = "hello world";
        Log.e("查找", String.valueOf(str.indexOf("l")));
        Log.e("查找", String.valueOf(str.indexOf("p")));
        Log.e("查找", String.valueOf(str.indexOf("l", 5)));
        Log.e("查找", String.valueOf(str.indexOf("l", -1)));
        Log.e("查找", String.valueOf(str.indexOf("l", 20)));
        
        // 输出:
        E/查找: 2
        E/查找: -1
        E/查找: 9
        E/查找: 2
        E/查找: -1
    
  • 小结
    - indexOf 是按照“从左往右”的顺序查找
    - lastIndexOf 是按照“从右往左”的顺序查找
    - 查找到则返回所在位置,没有查找到则返回 -1

JS indexOflastIndexOfsearch

  • 方法

        /**
         * 从源字符串的 fromIndex 位置处按照“从左往右”顺序查找 searchValue “第一次”出现的位置
         * 1、 fromIndex 是可选值,不填写值默认从 位置0 开始,小于0(<0)也是从 位置0 开始,超过字符串长度范围,从length -1 处开始
         * 2、查找到则返回所在位置,没有查找到则返回 -1
         * 3、该方法是大小写敏感的
         */
        str.indexOf(searchValue[, fromIndex])
        
        /**
         * 从源字符串的 fromIndex 位置处按照“从右往左”顺序查找 searchValue “第一次”出现的位置,
         * 1、 fromIndex 是可选值,不填写值默认从 位置0 开始,小于0(<0)也是从 位置0 开始,超过字符串长度范围,从length -1 处开始
         * 2、查找到则返回所在位置,没有查找到则返回 -1
         */
        str.lastIndexOf(searchValue[, fromIndex])
        
        /**
         * 根据正则表达式查找内容
         * 1、查找到则返回所在位置,没有查找到则返回 -1
         */
        str.search(regexp)
        
        /*
         * 没有匹配到返回 null
         * 匹配到返回匹配的结果数组
         */
        str.match(regexp)
    
  • 例子

        //从左往右查找
        var str = "hello world"
        var index = str.indexOf("l")
        var index2 = str.indexOf("")
        var index3 = str.indexOf("987")
        var index4 = str.indexOf("l", 5)
        var index5 = str.indexOf("l", 20)
        var index6 = str.indexOf("l", -20)
        var index7 = str.indexOf("L")
        
        console.log(index)
        console.log(index2)
        console.log(index3)
        console.log(index4)
        console.log(index5)
        console.log(index6)
        console.log(index7)
        
        //输出:
        2
        0
        -1
        9
        -1
        2
        -1
        
        //从右往左查找
        var str = "hello world"
        var index = str.lastIndexOf("l")
        var index2 = str.lastIndexOf("")
        var index3 = str.lastIndexOf("987")
        var index4 = str.lastIndexOf("l", 5)
        var index5 = str.lastIndexOf("l", 20)
        var index6 = str.lastIndexOf("l", -20)
        var index7 = str.lastIndexOf("L")
        
        
        console.log(index)
        console.log(index2)
        console.log(index3)
        console.log(index4)
        console.log(index5)
        console.log(index6)
        console.log(index7)
        
        //输出:
        9
        11
        -1
        3
        9
        -1
        -1
        
        
        //正则表达式查找
        var str = "hello world 987 HELLO WORLD"
        var index = str.search(/[0-9]/)
        var index2 = str.search(/7/)
        var index3 = str.search(/[.]/)
        
        console.log(index)
        console.log(index2)
        console.log(index3)
        
        //输出:
        12
        14
        -1
        
        //正则表达式匹配查找
        var str = "hello 123 world 987 and 951"
        var result = str.match(/[0-9]+/g)
        
        console.log(result)
        //输出:
        ["123", "987", "951"]
    
  • 小结
    - indexOf 是按照“从左往右”的顺序查找
    - lastIndexOf 是按照“从右往左”的顺序查找
    - 查找到则返回所在位置,没有查找到则返回 -1
    - fromIndex 都是按照从左往右计算的

小结

  • JavaJS 的查找位置方法类似(indexOflastIndexOf)、查找到的位置,OC 查找到的是范围range

十、替换 replace

OC replace

  • 方法

        //把“源字符串”中所有的target字符替换为replacement
        - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        
        //把“源字符串”中searchRange范围内的target字符替换为replacement,通过options进行相关的控制,如忽略大小写,传0表示什么都不做
        - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        
        //把“源字符串”中range范围的字符,替换为replacement
        - (NSString *)stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        
        //可变字符串--
        - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString;
        - (NSUInteger)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange;
    
  • 例子

        //“源字符串”的所有范围内查找,替换
        NSString *str = @"hello world";
        NSString *result = [str stringByReplacingOccurrencesOfString:@"l" withString:@"0"];
        NSLog(@"%@", result);
        //输出:
        he00o wor0d
        
        NSString *str = @"hello world";
        NSString *result = [str stringByReplacingOccurrencesOfString:@"ll" withString:@"0"];
        NSLog(@"%@", result);
        //输出:
        he0o world
        
        
        //“源字符串”的range范围内查找,替换
        NSString *str = @"hello world";
        NSString *result = [str stringByReplacingOccurrencesOfString:@"l" withString:@"0" options:0 range:NSMakeRange(0, 5)];
        NSLog(@"%@", result);
        //输出:
        he00o world
        
        //忽略大小写的查找替换 L l
        NSString *str = @"hello world AND HELLO WORLD";
        NSString *result = [str stringByReplacingOccurrencesOfString:@"L" withString:@"+" options:NSCaseInsensitiveSearch range:NSMakeRange(0, str.length)];
        NSLog(@"%@", result);
        //输出:
        he++o wor+d AND HE++O WOR+D
        
        //正则表达式查找字符串,并替换
        NSString *str = @"hello world 12345679 hello";
        NSString *result = [str stringByReplacingOccurrencesOfString:@"[0-9]+" withString:@"+" options:NSRegularExpressionSearch range:NSMakeRange(0, str.length)];
        NSLog(@"%@", result);
        //输出:
        hello world + hello
        
        
        //“源字符串”range范围内的字符替换为响应的字符串
        NSString *str = @"hello world";
        NSString *result = [str stringByReplacingCharactersInRange:NSMakeRange(0, 5) withString:@"+"];
        NSLog(@"%@", result);
    
  • 小结
    - 在“源字符”的全部范围进行查找、替换;- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    - 在“源字符”的range范围进行查找替换;- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    - 把“源字符”range范围的子字符串替换;- (NSString *)stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    - “源字符串”全部/range范围进行全部/部分字符替换

Java replace

  • 方法

        //用新字符newChar替换掉旧字符串oldChar
        public String replace(char oldChar, char newChar)
        //用心的字符串replacement替换掉目标字符串target
        public String replace(CharSequence target, CharSequence replacement)
        //用字符串replacement替换掉“所有”通过正则表达式regex查找的内容
        public String replaceAll(String regex, String replacement)
        //用字符串replacement替换掉“第一个”通过正则表达式regex查找的内容
        public String replaceFirst(String regex, String replacement)
    
  • 例子

        String str = "hello world 12345679 HELLO WORLD  987654";
        String result = str.replace('l', '+');
        Log.d("替换:", result);
        
        String result2 = str.replace("ll", "+");
        Log.d("替换:", result2);
        
        String result3 = str.replaceAll("[0-9]+", "+");
        Log.d("替换:", result3);
        
        String result4 = str.replaceFirst("[0-9]+", "+");
        Log.d("替换:", result4);
        
        //输出:
        he++o wor+d 12345679 HELLO WORLD  987654
        he+o world 12345679 HELLO WORLD  987654
        hello world + HELLO WORLD  +
        hello world + HELLO WORLD  987654
    
  • 小结

JS replace

  • 方法

        /**
         * “源字符”中把查找到的内容(可以是“字符串常量substr”,也可以是“正则表达式regexp”) 用 newSubstr 进行替换
         * ps:
         *      1、不会改变“源字符串”的值
         *      2、替换的是“第一个”查找到的内容
         *      3、如果需要替换“所有”查找到的内容,需要使用正则表达式,加上 g 描述 (global的缩写)
         *      4、如果需要“忽略大小写”的查找替换,需要使用正则表达式,加上 i 描述
         */
        str.replace(regexp|substr, newSubstr|function)
    
  • 例子

        //查找字符串常量并替换
        var str = "hello world 01123 AND HELLO WORLD 321445"
        var result = str.replace("l", "+")
        console.log(str)
        console.log(result)
        //输出:
        hello world 01123 AND HELLO WORLD 321445
        he+lo world 01123 AND HELLO WORLD 321445
        
        //正则表达式替换所有查找到的内容
        var str = "hello world 01123 AND HELLO WORLD 321445"
        var result = str.replace(/l/g, "+")
        console.log(str)
        console.log(result)
        //输出:
        hello world 01123 AND HELLO WORLD 321445
        he++o wor+d 01123 AND HELLO WORLD 321445
        
        
        //忽略大小写的,使用真正表达式替换所有查找到的内容
        var str = "hello world 01123 AND HELLO WORLD 321445"
        var result = str.replace(/l/gi, "+")
        console.log(str)
        console.log(result)
        //输出:
        hello world 01123 AND HELLO WORLD 321445
        he++o wor+d 01123 AND HE++O WOR+D 321445
    
  • 小结
    - 替换字符串常量,使用引号"""l"),使用正则表达式,/开始,/结束, 不需要加引号"",(/l/
    - 查找替换全部使用g标志
    - 忽略大小写使用i标志

小结

  • replace 进行替换操作

十一、截取字符串 sub

OC substring

  • 方法

        //包含index位置的内容
        - (NSString *)substringFromIndex:(NSUInteger)from;
        //不包含index位置的内容
        - (NSString *)substringToIndex:(NSUInteger)to;
        - (NSString *)substringWithRange:(NSRange)range;
        
        // 字符序列判中字符范围判断
        - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
        - (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    
  • 例子

        NSString *str = @"0123456789";
        NSString *substringFrom = [str substringFromIndex:5];
        NSString *substringTo = [str substringToIndex:5];
        NSString *substringRange = [str substringWithRange:NSMakeRange(1, 4)];
        NSLog(@"From:%@", substringFrom); //From:56789
        NSLog(@"To:%@", substringTo); //To:01234
        NSLog(@"Range:%@", substringRange); //Range:1234
    
    但是对于显示的内容需要多个`unicode`编码组成的内容(如`emoji`表情),使用上面的方法会导致`emoji`表情从中间被截断,导致内容显示异常,所以需要使用下面的方法:
    
        //未处理前--------
        NSString *str = @"0123\U0001F42E456789";
        NSString *substringFrom = [str substringFromIndex:5];
        NSString *substringTo = [str substringToIndex:5];
        NSString *substringRange = [str substringWithRange:NSMakeRange(1, 4)];
        NSLog(@"str:%@", str); //str:0123?456789
        NSLog(@"length:%ld", str.length); //length:12
        NSLog(@"From:%@", substringFrom); //From:\udc2e456789
        NSLog(@"To:%@", substringTo); //To:0123
        NSLog(@"Range:%@", substringRange); //Range:123
        
        //处理后--------
        NSString *str = @"0123\U0001F42E456789";
        NSString *substringFrom = [str substringFromIndex:[str rangeOfComposedCharacterSequenceAtIndex:5].location];
        NSString *substringTo = [str substringToIndex:NSMaxRange([str rangeOfComposedCharacterSequenceAtIndex:5])];
        NSString *substringRange = [str substringWithRange:[str rangeOfComposedCharacterSequencesForRange:NSMakeRange(1, 4)]];
        NSLog(@"str:%@", str); //str:0123?456789
        NSLog(@"length:%ld", str.length); //length:12
        NSLog(@"From:%@", substringFrom); //From:?456789
        NSLog(@"To:%@", substringTo); //To:0123?
        NSLog(@"Range:%@", substringRange); //Range:123?
    
  • 小结
    - 可以看到,经过处理之后的字符串截取,避免了字符串的截取位置导致的显示异常,处理之后的字符串截取结果正常,也符合实际情况;

Java substring

  • 方法

        // “源字符串” 从 beginIndex 开始,一直截取到字符串末尾
        public String substring(int beginIndex)
        // “源字符串” 从 beginIndex 开始,一直截取到 endIndex 位置
        public String substring(int beginIndex, int endIndex)
        public CharSequence subSequence(int beginIndex, int endIndex)
    
  • 例子

        String str = "0123456789";
        
        String substringFrom = str.substring(5);
        String substringTo = str.substring(0, 5);
        String substringRange = str.substring(1, 5);
        Log.e("substringFrom:", substringFrom);
        Log.e("substringTo:", substringTo);
        Log.e("substringRange:", substringRange);
        
        // 输出:
        E/substringFrom:: 56789
        E/substringTo:: 01234
        E/substringRange:: 1234
    
  • 小结

    • 如果 beginIndexendIndex,如果 endIndex 大于 length()beginIndex 大于 startIndex , 会抛出异常

JS substringsubstrslice

  • 方法

        /**
         * 截取“源字符串”的 indexStart 位置到 indexEnd 位置的子字符串
         * 1、包含 indexStart 位置字符,不包含 indexEnd 位置字符
         * 2、如果 indexStart 和 indexEnd 相等,返回空字符串 ''
         * 3、如果索引 index 小于 0 或者索引 index 为 NaN ,则当成 0 处理
         * 4、如果索引 index 大于 length,当成 length  处理
         * 5、参数 indexStart 和 indexEnd ,从这两者中 较小 的索引位置处开始截取,一直到 较大 的索引位置处,即使 indexStart 大于 indexEnd
         */
        str.substring(indexStart[, indexEnd])
        
        /**
         * 从“源字符串”的 start 位置处开始截取 length 长度的子字符串
         * 1、如果索引 start 小于 0 ,看成是 length + start , 如果 length + start 结果小于 0 ,当成 0 处理
         * 2、如果索引 start 为 NaN ,则当成 0 处理
         * 3、如果索引 start 大于 length ,返回空字符 ''
         * 4、length 是可选的,如果不传入参数,默认是 截取到字符串的结尾处
         * 5、如果 length 为 0 或者 负值,返回空字符串 ''
         */
        str.substr(start[, length])
        
        /**
         * 提取源字符串的 beginSlice(包含) 位置到 endSlice(不包含)位置的字符串
         * 1、如果 beginSlice 或者 endSlice 为负数,则最终的索引值为 length + index
         * 2、endSlice 为负数,可以看成是源字符串从后往前的索引(不包含)
         * 3、如果 beginSlice 小于 endSlice ,返回空字符串 ''
         */
        str.slice(beginSlice[, endSlice])
    
  • 例子

        //范围截取
        var str = "0123456789";
        var substringFrom = str.substring(5);
        var substringTo = str.substring(0, 5);
        var substringRange = str.substring(1, 5);
        console.log("substringFrom:", substringFrom); 
        console.log("substringTo:", substringTo); 
        console.log("substringRange:", substringRange);
        
        //输出:
        substringFrom: 56789
        substringTo: 01234
        substringRange: 1234
        
        //截取的特殊情况
        var str = "0123456789";
        console.log(str.substring(1, 1));   
        console.log(str.substring(0, 5)); 
        console.log(str.substring(-2, 5));
        console.log(str.substring(NaN, 5));
        console.log(str.substring(5, 15));
        console.log(str.substring(5, -10));
        console.log(str.substring(5, 2));
        console.log(str.substring(2, 5));
        console.log(str.substring(5, 9));
        console.log(str.substring(5, 10));
        console.log(str.substring(5, 11));
        
        //输出:
         
        01234
        01234
        01234
        56789
        01234
        234
        234
        5678
        56789
        56789
        
        
        //长度截取
        var str = "0123456789";
        console.log(str.substr(5));
        console.log(str.substr(0, 5));
        console.log(str.substr(20));
        console.log(str.substr(-20));
        console.log(str.substr(NaN));
        console.log(str.substr(-5, 2));
        console.log(str.substr(-20, 2));
        console.log(str.substr(5, -1));
        console.log(str.substr(5, 0));
        console.log("++++++++")
        //输出:
        56789
        01234
        
        0123456789
        0123456789
        56
        01
        
        
        ++++++++
        
        
        
        
        var str = 'hello world';
        var result = str.slice(1, 5);
        console.log(result);
        
        var result2 = str.slice(1, -1);
        console.log(result2);
        
        var result3 = str.slice(1, -2);
        console.log(result3);
        
        var result4 = str.slice(1, 0);
        console.log(result4);
        
        console.log("++++++++")
        
        //输出:
        ello
        ello worl
        ello wor
        
        ++++++++
    
  • 小结
    1. substring 范围截取
    - 判断 indexStartindexEnd ,如果 小于 0 或者为 NaN ,则当成 0 处理,如果 大于 length ,当成 length 处理
    - 从 indexStartindexEnd较小的位置处开始截取,一直到较大的位置
    - 如果 indexStartindexEnd 相等,返回空字符串''
    - 如果 只有一个参数 indexStart ,则表示从indexStart开始,一直到字符串结尾,等价于 indexStartlength
    - 如果 indexStart 小于 indexEndsubstring(indexStart, indexEnd) 等价于 substring(indexEnd, indexStart) ,如上面的 str.substring(5, 2)str.substring(2, 5)
    1. substr 长度截取
    - 判断 start 数值,小于 0 ,看成是 length + start , 如果 length + start 结果小于 0 ,当成 0 处理
    - 索引 startNaN ,则当成 0 处理
    - 如果索引 start 大于 length - 1 ,返回空字符 ''
    - length 是可选的,如果不传入参数,默认是 截取到字符串的结尾
    - 如果 length0 或者 负值,返回空字符串 ''

小结

十二、大小写 uppercaselowercase

OC uppercaseStringlowercaseStringcapitalizedString

  • 大写

      @property (readonly, copy) NSString *uppercaseString;
    
  • 小写

      @property (readonly, copy) NSString *lowercaseString;
    
  • 首字母大写

      @property (readonly, copy) NSString *capitalizedString;
    
  • 例子:

      NSString *str = @"Hello world";
      NSLog(@"%@", str.uppercaseString);
      NSLog(@"%@", str.lowercaseString);
      NSLog(@"%@", str.capitalizedString);
      
      //打印:
      HELLO WORLD
      hello world
      Hello World
    

    地区化

      /* The following three return the locale-aware case mappings. They are suitable for strings presented to the user.
      */
      @property (readonly, copy) NSString *localizedUppercaseString API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
      @property (readonly, copy) NSString *localizedLowercaseString API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
      @property (readonly, copy) NSString *localizedCapitalizedString API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
      
      /* The following methods perform localized case mappings based on the locale specified. Passing nil indicates the canonical mapping.  For the user preference locale setting, specify +[NSLocale currentLocale].
      */
      - (NSString *)uppercaseStringWithLocale:(nullable NSLocale *)locale API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));
      - (NSString *)lowercaseStringWithLocale:(nullable NSLocale *)locale API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));
      - (NSString *)capitalizedStringWithLocale:(nullable NSLocale *)locale API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));
    

Java toUpperCasetoLowerCase

  • 大写

      public String toUpperCase() { }
    
  • 小写

      public String toLowerCase() { }
    
  • 例子:

      String str = "Hello world";
      Log.d("大小写", str.toUpperCase());
      Log.d("大小写", str.toLowerCase());
      
      //打印
      HELLO WORLD
      hello world
    

    地区化

      public String toUpperCase(Locale locale) { }
      public String toLowerCase(Locale locale) { }
    

JS toUpperCasetoLowerCase

  • 大写

      str.toUpperCase()
      //有返回值,返回值为"大写"字母,不会影响原来字符串"str"的值
    
  • 小写

      str.toLowerCase()
      //有返回值,返回值为"小写"字母,不会影响原来字符串"str"的值
    
  • 例子:

      var str = "hello world"
      console.log(str.toUpperCase())
      console.log(str.toLowerCase())
      
      //打印:
      HELLO WORLD
      hello world
    

    地区化:

      str.toLocaleLowerCase()
      str.toLocaleLowerCase(locale) 
      str.toLocaleLowerCase([locale, locale, ...])
      
      str.toLocaleUpperCase()
      str.toLocaleUpperCase(locale) 
      str.toLocaleUpperCase([locale, locale, ...])
    

小结

  • 大写:uppercase
  • 小写:lowercase

十三、过滤 trim

OC trim

  • 方法

        // 过滤字符串中的 首尾 在字符结合 set 中的字符
        - (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
    
  • 例子

        NSString *str = @" \r \n \f \t \v  hello \r \n \f \t \v ";
        NSString *result = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSLog(@"%@", result);
        
        // 输出:
        hello
    
  • 小结

Java trim

  • 方法

        public String trim()
    
  • 例子

        String str = " \r \n  hello \r \n  ";
        String result = str.trim();
        Log.e("过滤", result);
        
        //输出:
        E/过滤: hello
    
  • 小结

JS trim

  • 方法

        //过滤首尾空白字符
        str.trim()
    
  • 例子

        var str = " \r \n \f \t \v \ufeff hello \r \n \f \t \v \ufeff "
        var result = str.trim()
        
        console.log(result)
        //输出:
        hello
    
  • 小结

小结

十四、正则表达式 regexmatch

相关知识

  • 格式 /pattern/flags

  • pattern中符号含义
    - . : 表示除了行结束符(\n\r\u2028\u2029)以外的任意字符;在字符集[]中匹配的是一个字面量.

          var str = "hello world 987 . HELLO WORLD"
          var result = str.search(/./)
          var result2 = str.search(/[.]/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          0
          16
    
    - `\d` : 表示匹配任意的阿拉伯数字,即 `0-9`,`\d` 和 `[0-9]` 两者等价
    
          var str = "hello world 987 . HELLO WORLD"
          var result = str.search(/\d/)
          var result2 = str.search(/[0-9]/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          12
          12
    
    - `\D` : 表示匹配任意的`非`阿拉伯数字,`\D` 和 `[^0-9]` 两者等价
    
          var str = "hello world 987 . HELLO WORLD"
          var result = str.search(/\D/)
          var result2 = str.search(/[^0-9]/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          0
          0
    
    - `\w` : 表示匹配任意的`大写字母`、`小写字母`、`阿拉伯数字`、`下划线`,`\w` 和 `[A-Za-z0-9_]` 两者等价
    
          var str = "% hello WORLD _ . "
          var result = str.search(/\w/)
          var result2 = str.search(/[A-Za-z0-9_]/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          2
          2
    
    - `\W` : 表示匹配任意的`“非”` `大写字母`、`小写字母`、`阿拉伯数字`、`下划线`,`\W` 和 `[^A-Za-z0-9_]` 两者等价
    
          var str = "hello % WORLD _ . "
          var result = str.search(/\W/)
          var result2 = str.search(/[^A-Za-z0-9_]/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          5
          5
    
    - `\s` : 表示匹配任意的`空白符`,包含`空格`、`制表符`(`\t` 和 `\v`)、`换页符`(`\f`)、`换行符`(`\r` 和 `\n`)和`其他 Unicode 空格`,`\s` 和 `[ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] ` 两者等价
    
          var str = "hello % WORLD _ . "
          var result = str.search(/\s/)
          var result2 = str.search(/`[ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]`/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          5
          5
    
    - `\S` : 表示匹配任意的 `非` `空白符`,`\S` 和 `[^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]` 两者等价
    
          var str = "hello % WORLD _ . "
          var result = str.search(/\S/)
          var result2 = str.search(/[^ `[^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]`/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          0
          0
          
    
    - `\t` : 匹配一个水平制表符(tab)
    - `\v` : 匹配一个垂直制表符(vertical tab)
    - `\r` : 匹配一个回车符(carriage return)
    - `\n` : 匹配一个换行符(linefeed)
    - `\f` : 匹配一个换页符(form-feed)
    - `[\b]` : 匹配一个退格符(backspace)(不要与 `\b` 混淆)
    - `\0` : 匹配一个 `NUL` 字符。不要在此后面跟小数点
    - `\cX` : `X` 是 `A - Z` 的一个字母。匹配字符串中的一个`控制`字符
    - `\xhh` : 匹配编码为 `hh` (两个十六进制数字)的字符
    - `\uhhhh` : 匹配 `Unicode` 值为 `hhhh` (四个十六进制数字)的字符
    
          var str = "hello ɀ 013a"
          var result = str.search(/\u0240/)
          var result2 = str.search(/\u0068/) //u0068 对应的字符 为 h
          
          console.log(result)
          console.log(result2)
          
          //输出:
          6
          0
    
    - `\`  : 把特殊字符当做字面意义解释;`*` 是一个特殊字符,表示匹配某个字符 0 或多次,如 `/a*/` 意味着 0 或多个 "`a`"。 为了匹配字面意义上的 `*`,在它前面加上一个反斜杠,例如,`/a\*/`匹配 `'a*'`
    - `[]`  : 字符集合,表示匹配`集合中`的任意一个字符,可以使用连字符`-`指定一个范围,如 `[abcd]` 等价于 `[a-d]`
    - `[^]` : 反义字符集合,表示匹配字符`集合以外`的字符,可以使用连字符`-`指定一个范围,`[^abc]` 等价于 `[^a-c]`
    - `^` : 匹配输入的开始,`/^A/` 不匹配 "`an A`" 中的 "`A`",但匹配 "`An A`" 中的 "`A`";`^` 在`字符集合`中表示`相反`的意思,但是在正则表达式直接量中表示字符开始;有点类似`前缀`
    
          var str = "hello ɀ 013a"
          var result = str.search(/^h/)
          var result2 = str.search(/^l/)
          
          console.log(result)
          console.log(result2)
          
          //输出:
          0
          -1
    
    - `$` : 匹配输入结尾,`/t$/` 不匹配 "`eater`" 中的 "`t`",但匹配 "`eat`" 中的 "`t`",有点类似`后缀`
    
          var str = "eater"
          var result = str.search(/t$/)
          var result2 = str.search(/r$/)
          
          console.log(result)
          console.log(result2)
          //输出:
          -1
          4
    
    - `\b` : 匹配一个零宽`单词边界`,`/\b.../`,以`...`开始的单词,`/...\b/`,以`...`结尾的单词;`/\bno/` 匹配 "at noon" 中的 "no",`/ly\b/` 匹配 "possibly yesterday." 中的 "ly";
    
          var str = "at noon"
          var result = str.search(/\bno/)
          
          console.log(result)
          //输出:
          3
    
    - `\B` : 匹配一个零宽非单词边,`/\Bon/` 匹配 "at noon" 中的 "on",`/ye\B/` 匹配 "possibly yesterday." 中的 "ye"
    - `(x)` : 匹配 `x` 并且`捕获匹配项结果`。 这被称为捕获括号`(capturing parentheses)`。被匹配的子字符串`可以`在结果数组的元素 `[1], ..., [n]` 中找到,或在被定义的 `RegExp` 对象的属性 `$1, ..., $9` 中找到。会消耗性能。
    
          var str = "hello 123 world 987 and 951"
          var result = str.match(/([0-9]+)/g)
          
          console.log(result)
          //输出:
          ["123", "987", "951"]
    
    - `(?:x)` : 匹配 `x` `不会`捕获匹配项。这被称为非捕获括号`(non-capturing parentheses)`。匹配项`不能`够从结果数组的元素 `[1], ..., [n]` 或已被定义的 `RegExp` 对象的属性 `$1, ..., $9` 再次访问到。
    
          var str = "hello 123 world 987 and 951"
          var result = str.match(/(?:[0-9]+)/g)
          
          console.log(result)
          //输出:
          ["123", "987", "951"]
    
    - `x*` : 匹配前面的模式 x `0 或多次`。例如,`/bo*/` 匹配 "`A ghost booooed`" 中的 "`boooo`","`A bird warbled`" 中的 "`b`",但是不匹配 "`A goat grunted`"。
    - `x+` : 匹配前面的模式 x `1 或多次`。等价于 `{1,}`。例如,`/a+/` 匹配 "`candy`" 中的 "`a`","`caaaaaaandy`" 中`所有`的 "`a`"。
    - `x?` : 匹配前面的模式 x `0 或 1 次`。
    - `x(?=y)` : 只有当 `x` 后面紧跟着 `y` 时,才匹配 `x`。 例如,`/Jack(?=Sprat)/` 只有在 '`Jack`' 后面紧跟着 '`Sprat`' 时,才会匹配它。`/Jack(?=Sprat|Frost)/` 只有在 '`Jack`' 后面紧跟着 '`Sprat`' 或 '`Frost`' 时,才会匹配它。然而,'`Sprat`' 或 '`Frost`' 都`不是`匹配结果的一部分。
    - `x(?!y)` : 只有当 `x` 后面`不是`紧跟着 `y` 时,才匹配 `x`。例如,`/\d+(?!\.)/` 只有当一个数字后面没有紧跟着一个小数点时,才会匹配该数字。`/\d+(?!\.)/.exec("3.141")` 匹配 `141` 而不是 `3.141`。
    - `x|y` : 匹配 `x` 或 `y` **,例如,`/green|red/` 匹配 "`green apple`" 中的 ‘`green`',"`red apple`." 中的 '`red`'。
    - `x{n}` : `n` 是一个正整数。前面的模式 x `连续出现 n 次时匹配`。
    - `x{n,}` : `n` 是一个正整数。前面的模式 x `连续出现至少 n 次时匹配`。
    - `x{n,m}` : `n` 和 `m` 为正整数。前面的模式 x `连续出现至少 n 次,至多 m 次时匹配`。
    
    • flags中符号含义
      • g : 全局匹配;找到所有匹配,而不是在第一个匹配后停止
      • i : 忽略大小写
      • m : 多行; 将开始和结束字符(^$)视为在行上工作(也就是,分别匹配每一行的开始和结束(由 \n\r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
      • u : Unicode; 将模式视为Unicode序列点的序列
      • y : 粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。

OC

详情见 `NSRegularExpression` 类

Java matches

  • 方法

        public boolean matches(String regex)
        Pattern.matches( regex , str )
    
  • 例子

        String str = "hello 123 world 987 and 951";
        boolean result = str.matches("[0-9]+");
        Log.e("正则表达式", String.valueOf(result));
        // 输出:
        E/正则表达式: false
        
        
        String str = "123456";
        boolean result = str.matches("[0-9]+");
        Log.e("正则表达式", String.valueOf(result));
        // 输出:
        E/正则表达式: true
    
  • 小结
    - matches 是全局匹配,即整个字符串都是匹配的才返回true,否则返回 false

JS match

  • 方法

        /*
         * 没有匹配到返回 null
         * 匹配到返回匹配的结果数组
         */
        str.match(regexp)
        
        /**
         * 根据正则表达式查找内容
         * 1、查找到则返回所在位置,没有查找到则返回 -1
         */
        str.search(regexp)
    
  • 例子

        var str = "hello 123 world 987 and 951"
        var result = str.match(/[0-9]+/g)
        
        console.log(result)
        //输出:
        ["123", "987", "951"]
    
  • 小结

小结

十五、字符串和其他类型的转化 parsevalueOf

OC

  • 字符串转数字等

        @property (readonly) double doubleValue;
        @property (readonly) float floatValue;
        @property (readonly) int intValue;
        @property (readonly) NSInteger integerValue API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        @property (readonly) long long longLongValue API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        @property (readonly) BOOL boolValue API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    
  • 数字等转字符串

        - (instancetype)initWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
        - (instancetype)initWithFormat:(NSString *)format arguments:(va_list)argList NS_FORMAT_FUNCTION(1,0);
        + (instancetype)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
        
        - (instancetype)initWithFormat:(NSString *)format locale:(nullable id)locale, ... NS_FORMAT_FUNCTION(1,3);
        - (instancetype)initWithFormat:(NSString *)format locale:(nullable id)locale arguments:(va_list)argList NS_FORMAT_FUNCTION(1,0);
        + (instancetype)localizedStringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
    

Java valueOf

  • 字符串转数字等

        public static Integer valueOf(String s)
        .... 依次类推
    
  • 数字等转字符串

        public static String valueOf(boolean b)
        public static String valueOf(char c)
        public static String valueOf(int i)
        public static String valueOf(long l)
        public static String valueOf(float f)
        public static String valueOf(double d)
    

JS parseIntparseFloattoString+

  • 字符串转数字
    - 方法

          /**
           * 把字符串 string 转化为 radix 进制的整数数值,返回值为 整数number 或 NaN
           * 1、要明确给出radix参数的值
           * 2、在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理:
           *   - 如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
           *   - 如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
           *   - 如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
           */
          parseInt(string, radix);
          
          /**
           * 把字符串 string 转化为 radix 进制的小数数值,返回值为 小数number 或 NaN
           */
          parseFloat(string)
    
    - 例子
    
          console.log(parseInt('0Xa0'))
          console.log(parseInt('010'))
          console.log(parseInt('08'))
          console.log(parseInt('20'))
          
          //输出:
          160
          10
          8
          20
    
    - 小结
      - 参数 `radix` 需要指定,防止一些不必要的错误
      - 当无法转化为数字时,返回`NaN`
    
  • 数字转字符串
    - 方法

          /**
           * 把数字转化为 radix进制的字符串形式
           * 1、radix :可选值,不传默认为10进制
           * 2、radix :取值 2-36 之间的整数,其他会抛出异常RangeError
           */
          numObj.toString([radix])
          
          //使用加号+拼接 
          '' + number
    
    - 例子
    
          var num = 123;
          console.log(num.toString());
          console.log('' + 123);
          
          //输出:
          123
          123
    
    - 小结
    

十六、分割字符串为数组 Separatedsplit

OC Separated

  • 方法

        // 根据 指定的字符串 separator 进行分割
        - (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;
        // 根据 指定的字符集合 separator 进行分割
        - (NSArray<NSString *> *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    
  • 例子

        NSString *str = @"hello 123 world 456 nice 987";
        NSArray *array = [str componentsSeparatedByString:@" "];
        NSLog(@"%@", array);
        
        NSArray *array2 = [str componentsSeparatedByCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
        NSLog(@"%@", array2);
        
        // 输出:
        (
            hello,
            123,
            world,
            456,
            nice,
            987
        )
        
        (
            "hello ",
            "",
            "",
            " world ",
            "",
            "",
            " nice ",
            "",
            "",
            ""
        )
    
  • 小结
    - componentsSeparatedByString 是根据给定的字符串进行分割
    - componentsSeparatedByCharactersInSet 是根据给定的字符集合分割,查找到一个符合的字符就当成是一个分隔符进行分割,如上面的例子中 1231 进行分割一次得到 hello2 进行分割一次得到 ""3 进行分割一次得到 ""

Java split

  • 方法

        // 根据正则表达式 regex 分割字符串
        public String[] split(String regex)
        // 根据正则表达式 regex 分割字符串,最终是分割成 limit 部分
        public String[] split(String regex, int limit)
    
  • 例子

        String str = "hello 123 world 456 nice 987";
        String[] result = str.split(" ");
        Log.e("分割", String.valueOf(result.length));
        for (int i = 0; i < result.length; i++) {
            Log.e("分割", result[i]);
        }
        // 输出:
        E/分割: 6
        E/分割: hello
        E/分割: 123
        E/分割: world
        E/分割: 456
        E/分割: nice
        E/分割: 987
        
        String str = "hello 123 world 456 nice 987";
        String[] result = str.split("[\\d]+");
        Log.e("分割", String.valueOf(result.length));
        for (int i = 0; i < result.length; i++) {
            Log.e("分割", result[i]);
        }
        // 输出:
        E/分割: 3
        E/分割: hello 
        E/分割:  world 
        E/分割:  nice
        
        
        String str = "hello 123 world 456 nice 987";
        String[] result = str.split("[\\d]+", 2);
        Log.e("分割", String.valueOf(result.length));
        for (int i = 0; i < result.length; i++) {
            Log.e("分割", result[i]);
        }
        // 输出:
        E/分割: hello 
        E/分割:  world 456 nice 987
    
  • 小结
    - 会过滤最后的空字符 ""

JS split

  • 方法

        /**
         * 把字符串根据指定的分隔符 separator 进行分割字符串,返回字符串数组前 limit 个元素组成的子数组
         * 1、separator 可以是 字符串常量 或者 正则表达式
         * 2、对于正则表达式,如果需要返回匹配到的内容,需要加挂号 ()
         * 3、如果 字符串的第一个或者最后一个 和 分隔符匹配,也会进行分割,元素是空字符串 ""
         */
        str.split([separator[, limit]])
    
  • 例子

        var str = 'hello 123 world 456 nice 987';
        var result = str.split(' ');
        console.log(result);
        //输出: ["hello", "123", "world", "456", "nice", "987"]
        
        var result2 = str.split(' ', 2);
        console.log(result2);
        //输出: ["hello", "123"]
        
        var result3 = str.split(/\d+/);
        console.log(result3);
        //输出: ["hello ", " world ", " nice ", ""]
        //因为最后一个是数字,所以分割后的字符串数组,最后一个元素为空字符串
        
        var result4 = str.split(/(\d+)/);
        console.log(result4);
        //输出: ["hello ", "123", " world ", "456", " nice ", "987", ""]
    
  • 小结
    - 根据 字符串常量正则表达式 进行分割
    - 如果字符串的第一个或者最后一个 和 分隔符匹配,也会进行分割,元素是空字符串 ""

小结

  • jsoc 分割不会过滤最后的空字符 ""java 分割会过滤最后的空字符 ""

十七、编码

OC

概念

  • OC中的字符串NSSring是由有序UTF-16编码的"单元"(code unitscharacters)组成的
  • 长度length、索引index,范围range都是基于字符串的UTF-16的编码"单元"处理和操作的
  • "单元"code unitsunichar类型表示(无符号的short类型,typedef unsigned short unichar),2字节,16位,范围为0~32767

编码方式

      typedef NSUInteger NSStringEncoding;
      NS_ENUM(NSStringEncoding) {
          NSASCIIStringEncoding = 1,        /* 0..127 only */
          NSNEXTSTEPStringEncoding = 2,
          NSJapaneseEUCStringEncoding = 3,
          NSUTF8StringEncoding = 4,
          NSISOLatin1StringEncoding = 5,
          NSSymbolStringEncoding = 6,
          NSNonLossyASCIIStringEncoding = 7,
          NSShiftJISStringEncoding = 8,          /* kCFStringEncodingDOSJapanese */
          NSISOLatin2StringEncoding = 9,
          NSUnicodeStringEncoding = 10,
          NSWindowsCP1251StringEncoding = 11,    /* Cyrillic; same as AdobeStandardCyrillic */
          NSWindowsCP1252StringEncoding = 12,    /* WinLatin1 */
          NSWindowsCP1253StringEncoding = 13,    /* Greek */
          NSWindowsCP1254StringEncoding = 14,    /* Turkish */
          NSWindowsCP1250StringEncoding = 15,    /* WinLatin2 */
          NSISO2022JPStringEncoding = 21,        /* ISO 2022 Japanese encoding for e-mail */
          NSMacOSRomanStringEncoding = 30,
      
          NSUTF16StringEncoding = NSUnicodeStringEncoding,      /* An alias for NSUnicodeStringEncoding */
      
          NSUTF16BigEndianStringEncoding = 0x90000100,          /* NSUTF16StringEncoding encoding with explicit endianness specified */
          NSUTF16LittleEndianStringEncoding = 0x94000100,       /* NSUTF16StringEncoding encoding with explicit endianness specified */
      
          NSUTF32StringEncoding = 0x8c000100,                   
          NSUTF32BigEndianStringEncoding = 0x98000100,          /* NSUTF32StringEncoding encoding with explicit endianness specified */
          NSUTF32LittleEndianStringEncoding = 0x9c000100        /* NSUTF32StringEncoding encoding with explicit endianness specified */
      };
      
      //常用的:
      NSASCIIStringEncoding : ACII编码,只有0-127个字符
      NSUTF8StringEncoding : UTF-8编码,常用的,1个字节表示code point
      NSUnicodeStringEncoding : Unicode编码,国际统一的,2个字节表示一个code point

其他

      @property (readonly) NSStringEncoding fastestEncoding;        // Result in O(1) time; a rough estimate
      @property (readonly) NSStringEncoding smallestEncoding;       // Result in O(n) time; the encoding in which the string is most compact
      
      @property (class, readonly) const NSStringEncoding *availableStringEncodings;
      @property (class, readonly) NSStringEncoding defaultCStringEncoding;  // Should be rarely used
      
      + (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding;

字节大小

  • 方法

          //是否可以转化为相应的编码方式
          - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding;
          //“预估”转化为enc编码方式的所占的字节大小
          - (NSUInteger)maximumLengthOfBytesUsingEncoding:(NSStringEncoding)enc;  // Result in O(1) time; the estimate may be way over what's needed. Returns 0 on error (overflow)
          //“准确”计算转化为enc编码方式所占的字节大小
          - (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)enc;     // Result in O(n) time; the result is exact. Returns 0 on error (cannot convert to specified encoding, or overflow)
    
  • 例子

          NSString *str = @"hello world";
          if ([str canBeConvertedToEncoding:NSUTF8StringEncoding]) {
              NSUInteger maximumLength = [str maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding];
              NSUInteger length = [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
              NSLog(@"%ld", maximumLength);
              NSLog(@"%ld", length);
          } else {
              
          }
          
          //编码方式为 NSUTF8StringEncoding :
          33
          11
          
          //编码方式为 NSUTF16StringEncoding :
          22
          22
    
    UTF-8编码,一个单元`code points`用`8`位(1个字节byte)表示;UTF-16编码方式,一个单元`code points`用`16`位(2个字节byte)表示,所以才有了?的输出结果,UTF-16编码方式的字节数长度是UTF-8的`两倍`
    

字符串和二进制数据的转化

  • 方法

        [//NSSring](//nssring) 转 NSData 
        - (nullable NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)lossy;  
        - (nullable NSData *)dataUsingEncoding:(NSStringEncoding)encoding;                                  
        
        //NSData 转 NSSring
        - (nullable instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
    
  • 例子

        NSString *str = @"hello world";
        NSData *data = [str  dataUsingEncoding:NSUTF8StringEncoding];
        NSLog(@"%@", data);
        NSString *resultStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@", resultStr);
        
        //打印:
        <68656c6c 6f20776f 726c64>
        hello world
    

字符串和c语言字符串的转化

  • 方法

        //oc字符串转c字符串--------
        //转化为encoding编码方式的c语言字符串,支持8位编码,不支持UTF-16,UTF-32等非8位编码方式
        - (nullable const char *)cStringUsingEncoding:(NSStringEncoding)encoding NS_RETURNS_INNER_POINTER;
        - (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding;
        //快速的获取UTF-8编码方式的c语言字符串
        @property (nullable, readonly) const char *UTF8String NS_RETURNS_INNER_POINTER;
        
        
        //c字符串转oc字符串--------
        //c字符串cString通过enc编码方式转为oc字符串
        - (nullable instancetype)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
        + (nullable instancetype)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc;
        //c字符串nullTerminatedCString转化为UTF-8编码方式的oc字符串
        - (nullable instancetype)initWithUTF8String:(const char *)nullTerminatedCString;
        + (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
    
  • 例子

        //oc字符串转c字符串--------
        NSString *str = @"hello world";
        const char *UTF8Str = str.UTF8String;
        const char *ASCIIStr = [str cStringUsingEncoding:NSASCIIStringEncoding];
        const char *UTF16Str = [str cStringUsingEncoding:NSUTF16StringEncoding];
        NSLog(@"%s", UTF8Str);
        NSLog(@"%s", ASCIIStr);
        NSLog(@"%s", UTF16Str);
        
        //打印:
        hello world
        hello world
        h
        
        
        //c字符串转oc字符串--------
        const char *cStr = "hello world";
        NSString *ocStr = [[NSString alloc] initWithCString:cStr encoding:NSUTF16StringEncoding];
        NSLog(@"%@", ocStr);
            
        const char *UTF8Str = "hello world";
        NSString *str = [[NSString alloc] initWithUTF8String:UTF8Str];
        NSLog(@"%@", str);
        
        //打印:
        hello world
        hello world
    
    可以看到,使用`cStringUsingEncoding`方法进行编码时,如果传入的不是8位编码,会导致结果错误;
    

字符串和字节的转化

十八、保存到文件

OC

  • 方法

        - (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
        - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
    
  • 例子

  • 小结


最后吐槽一下: 这些原先是在notion上进行文章编辑的,后面导出为markdown的时候,有些格式混乱了,so 就变成了上面的样子了。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,055评论 0 13
  • 字符的 Unicode 表示法 codePointAt() String.fromCodePoint() 字符串的...
    卞卞村长L阅读 716评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,097评论 18 139
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,517评论 0 38
  • 2017年9月24日秋分后第一天,10点众姐妹来到国粹馆,第三期训练营开班了!汪桂花老师认真的教授着基础动作 挺胸...
    慧好聊吧阅读 303评论 1 3