From 38dbfc6cf86a7dd6f9c537bdb4dd3b59df61c6de Mon Sep 17 00:00:00 2001 From: Jason315 Date: Fri, 28 Jun 2019 15:05:03 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20issue=20#50:=20=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC=E6=A0=A1=E5=AF=B9=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jason315 --- docs/book/18-Strings.md | 50 ++++++++++------------------------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/docs/book/18-Strings.md b/docs/book/18-Strings.md index 16e1f8d..3d5ba8c 100644 --- a/docs/book/18-Strings.md +++ b/docs/book/18-Strings.md @@ -48,7 +48,7 @@ String x = Immutable.upcase(s); ## `+`的重载与`StringBuilder` `String`对象是不可变的,你可以给一个`String`对象添加任意多的别名。因为`String`是只读的,所以指向它的任何引用都不可能改它的值,因此,也就不会影响到其他引用。 -不可变性会带来一定的效率问题。为`String`对象重载的`+`操作符就是一个例子。重载的意思是,一个操作符在用于特定的类时,被赋予了特殊的意义(用于`String`的`+`与`+=`是Java中仅有的两个重载过的操作符,Java不允许程序员重载任何其他的操作符[^1])。 +不可变性会带来一定的效率问题。为`String`对象重载的`+`操作符就是一个例子。重载的意思是,一个操作符在用于特定的类时,被赋予了特殊的意义(用于`String`的`+`与`+=`是Java中仅有的两个重载过的操作符,Java不允许程序员重载任何其他的操作符 [^1])。 操作符`+`可以用来连接`String`: ```java @@ -469,7 +469,6 @@ Total 49.39 正如你所见,通过相当简洁的语法,`Formatter`提供了对空格与对齐的强大控制能力。在该程序中,为了恰当地控制间隔,格式化字符串被重复利用了多遍。 ### `Formatter`转换 下面的表格展示了最常用的类型转换: -<<<<<<< HEAD | 类型 | 含义 | | :----: | ---- | | `d` |整型(十进制)| @@ -482,19 +481,6 @@ Total 49.39 | `h` |散列码(十六进制)| | `%` |字面值“%”| 下面的程序演示了这些转换是如何工作的: -======= -|---|---| -|**`d`**|**整型(十进制)**| -|**`c`**|**Unicode字符**| -|**`b`**|**Boolean值**| -|**`s`**|**String**| -|**`f`**|**浮点数(十进制)**| -|**`e`**|**浮点数(科学计数)**| -|**`x`**|**整型(十六进制)**| -|**`h`**|**散列码(十六进制)**| -|**`%`**|**字符“%”**| -下面的程序演示了这些转换时如何工作的: ->>>>>>> beacc51a2ed07e07e476d69a2b4c1602e5b5ff4e ```java // strings/Conversion.java import java.math.*; @@ -693,7 +679,7 @@ public class Hex { ```java -? ``` -要描述一个整数,你可以说它有一位或多位阿拉伯数字。在正则表达式中,用`\d`表示一位数字。如果在其他语言中使用过正则表达式,那你可能就能发现Java对反斜线\的不同处理方式。在其他语言中,`\\`表示“我想要在正则表达式中插入一个普通的(字面上的)反斜线,请不要给它任何特殊的意义。”而在Java中,`\\`的意思是“我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。”例如,如果你想表示一位数字,那么正则表达式因该是`\\d`。如果你想插入一个普通的反斜线,应该这样写`\\\`。不过换行符和制表符之类的东西只需要使用单反斜线:`\n\t`。 +要描述一个整数,你可以说它有一位或多位阿拉伯数字。在正则表达式中,用`\d`表示一位数字。如果在其他语言中使用过正则表达式,那你可能就能发现Java对反斜线\的不同处理方式。在其他语言中,`\\`表示“我想要在正则表达式中插入一个普通的(字面上的)反斜线,请不要给它任何特殊的意义。”而在Java中,`\\`的意思是“我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。”例如,如果你想表示一位数字,那么正则表达式因该是`\\d`。如果你想插入一个普通的反斜线,应该这样写`\\\`。不过换行符和制表符之类的东西只需要使用单反斜线:`\n\t`。 [^2] 要表示“一个或多个之前的表达式”,应该使用`+`。所以,如果要表示“可能有一个负号,后面跟着一位或多位数字”,可以这样: ```java @@ -789,7 +775,7 @@ the mightiest banana in the forest...with... a banana! 稍后你会看到,`String`之外的正则表达式还有更强大的替换工具,例如,可以通过方法调用执行替换。而且,如果正则表达式不是只使用一次的话,非`String`对象的正则表达式明显具备更佳的性能。 ### 创建正则表达式 我们首先从正则表达式可能存在的构造集中选取一个很有用的子集,以此开始学习正则表达式。正则表达式的完整构造子列表,请参考JDK文档`java.util.regex`包中的`Pattern`类。 -<<<<<<< HEAD + | 表达式 | 含义 | | :---- | :---- | | `B` | 指定字符`B` | @@ -801,18 +787,6 @@ the mightiest banana in the forest...with... a banana! | `\f` | 换页 | | `\e` | 转义(Escape) | -======= -| | | -| ---- | ---- | -|**`B`**|**指定字符`B`**| -|**`\xhh`**|**十六进制值为`0xhh`的字符**| -|**`\uhhhh`**|**十六进制表现为`0xhhhh`的Unicode字符**| -|**`\t`**|**制表符Tab**| -|**`\n`**|**换行符**| -|**`\r`**|**回车**| -|**`\f`**|**换页**| -|**`\e`**|**转义Escape**| ->>>>>>> beacc51a2ed07e07e476d69a2b4c1602e5b5ff4e 当你学会了使用字符类(character classes)之后,正则表达式的威力才能真正显现出来。以下是一些创建字符类的典型方式,以及一些预定义的类: | 表达式 | 含义 | @@ -914,7 +888,7 @@ interface CharSequence { ### `Pattern`和`Matcher` 通常,比起功能有限的`String`类,我们更愿意构造功能强大的正则表达式对象。只需导入`java.util.regex`包,然后用`static Pattern.compile()`方法来编译你的正则表达式即可。它会根据你的`String`类型的正则表达式生成一个`Pattern`对象。接下来,把你想要检索的字符串传入`Pattern`对象的`matcher()`方法。`matcher()`方法会生成一个`Matcher`对象,它有很多功能可用(可以参考`java.util.regext.Matcher`的JDK文档)。例如,它的`replaceAll()`方法能将所有匹配的部分都替换成你传入的参数。 -作为第一个示例,下面的类可以用来测试正则表达式,看看它们能否匹配一个输入字符串。第一个控制台参数是将要用来搜索匹配的输入字符串,后面的一个或多个参数都是正则表达式,它们将被用来在输入的第一个字符串中查找匹配。在Unix/Linux上,命令行中的正则表达式必须用引号括起来。这个程序在测试正则表达式时很有用,特别是当你想验证它们是否具备你所期待的匹配功能的时候。 +作为第一个示例,下面的类可以用来测试正则表达式,看看它们能否匹配一个输入字符串。第一个控制台参数是将要用来搜索匹配的输入字符串,后面的一个或多个参数都是正则表达式,它们将被用来在输入的第一个字符串中查找匹配。在Unix/Linux上,命令行中的正则表达式必须用引号括起来。这个程序在测试正则表达式时很有用,特别是当你想验证它们是否具备你所期待的匹配功能的时候。[^3] ```java // strings/TestRegularExpression.java // Simple regular expression demonstration @@ -1059,7 +1033,7 @@ Bandersnatch.][frumious][Bandersnatch.] ``` 这首诗来自于Lewis Carroll所写的*Through the Looking Glass*中的“Jabberwocky”。可以看到这个正则表达式模式有许多圆括号分组,由任意数目的非空白符(`\\S+`)及随后的任意数目的空白符(`\\s+`)所组成。目的是捕获每行的最后3个词,每行最后以`\$`结束。不过,在正常情况下是将`\$`与整个输入序列的末端相匹配。所以我们一定要显示地告知正则表达式注意输入序列中的换行符。这可以由序列开头的模式标记`(?m)`来完成(模式标记马上就会介绍)。 ### `start()`和`end()` -在匹配操作成功之后,`start()`返回先前匹配的起始位置的索引,而`end()`返回所匹配的最后字符的索引加一的值。匹配操作失败之后(或先于一个正在进行的匹配操作去尝试)调用`start()`或`end()`将会产生`IllegalStateException`。下面的示例还同时展示了`matches()`和`lookingAt()`的用法[^4]: +在匹配操作成功之后,`start()`返回先前匹配的起始位置的索引,而`end()`返回所匹配的最后字符的索引加一的值。匹配操作失败之后(或先于一个正在进行的匹配操作去尝试)调用`start()`或`end()`将会产生`IllegalStateException`。下面的示例还同时展示了`matches()`和`lookingAt()`的用法 [^4]: ```java // strings/StartEnd.java import java.util.regex.*; @@ -1139,7 +1113,7 @@ lookingAt() start = 0 end = 14 matches() start = 0 end = 31 */ ``` -注意,`find()`可以在输入的任意位置定位正则表达式,而`lookingAt()`和`matches()`只有在正则表达式与输入的最开始处就开始匹配时才会成功。`matches()`只有在整个输入都匹配正则表达式时才会成功,而`lookingAt()`[^5]只要输入的第一部分匹配就会成功。 +注意,`find()`可以在输入的任意位置定位正则表达式,而`lookingAt()`和`matches()`只有在正则表达式与输入的最开始处就开始匹配时才会成功。`matches()`只有在整个输入都匹配正则表达式时才会成功,而`lookingAt()` [^5]只要输入的第一部分匹配就会成功。 ### `Pattern`标记 `Pattern`类的`compile()`方法还有另一个版本,它接受一个标记参数,以调整匹配行为: ```java @@ -1531,7 +1505,7 @@ But I'm not dead yet! I feel happy! But I'm not dead yet! I feel happy! */ ``` -使用正则表达式或`Scanner`对象,我们能够以更加复杂的模式来分割一个字符串,而这对于`StringTokenizer`来说就很困难了。基本上,我们可以放心地说,`StringTokenizer`已经可以废弃不用了[^2]。 +使用正则表达式或`Scanner`对象,我们能够以更加复杂的模式来分割一个字符串,而这对于`StringTokenizer`来说就很困难了。基本上,我们可以放心地说,`StringTokenizer`已经可以废弃不用了 [^2]。 @@ -1539,15 +1513,15 @@ But I'm not dead yet! I feel happy! 过去,Java对于字符串操作的技术相当不完善。不过随着近几个版本的升级,我们可以看到,Java已经从其他语言中吸取了许多成熟的经验。到目前为止,它对字符串操作的支持已经很完善了。不过,有时你还要在细节上注意效率问题,例如恰当地使用`StringBuilder`等。 -[^1]:C++允许编程人员任意重载操作符。这通常是很复杂的过程(参见Prentice Hall于2000年编写的《Thinking in C++(第2版)》第10章),因此Java设计者认为这是很糟糕的功能,不应该纳入到Java中。起始重载操作符并没有糟糕到只能自己去重载的地步,但具有讽刺意味的是,与C++相比,在Java中使用操作符重载要容易得多。这一点可以在Python(参见[www.Python.org](http://www.python.org))和C#中看到,它们都有垃圾回收机制,操作符重载也简单易懂。 +[^1]: C++允许编程人员任意重载操作符。这通常是很复杂的过程(参见Prentice Hall于2000年编写的《Thinking in C++(第2版)》第10章),因此Java设计者认为这是很糟糕的功能,不应该纳入到Java中。起始重载操作符并没有糟糕到只能自己去重载的地步,但具有讽刺意味的是,与C++相比,在Java中使用操作符重载要容易得多。这一点可以在Python(参见[www.Python.org](http://www.python.org))和C#中看到,它们都有垃圾回收机制,操作符重载也简单易懂。 -[^2]:Java并非在一开始就支持正则表达式,因此这个令人费解的语法是硬塞进来的。 +[^2]: Java并非在一开始就支持正则表达式,因此这个令人费解的语法是硬塞进来的。 -[^3]:网上还有很多实用并且成熟的正则表达式工具。 +[^3]: 网上还有很多实用并且成熟的正则表达式工具。 -[^4]:input来自于[Galaxy Quest](https://en.wikipedia.org/wiki/Galaxy_Quest)中Taggart司令的一篇演讲。 +[^4]: input来自于[Galaxy Quest](https://en.wikipedia.org/wiki/Galaxy_Quest)中Taggart司令的一篇演讲。 -[^5]:我不知道他们是如何想出这个方法名的,或者它到底指的什么。这只是代码审查很重要的原因之一。 +[^5]: 我不知道他们是如何想出这个方法名的,或者它到底指的什么。这只是代码审查很重要的原因之一。