# 操纵字符串中的字符

> 原文： [https://docs.oracle.com/javase/tutorial/java/data/manipstrings.html](https://docs.oracle.com/javase/tutorial/java/data/manipstrings.html)

`String`类有许多方法可用于检查字符串的内容，查找字符串中的字符或子字符串，更改大小写以及其他任务。

## 按索引获取字符和子字符串

您可以通过调用`charAt()`访问器方法获取字符串中特定索引处的字符。第一个字符的索引是 0，而最后一个字符的索引是`length()-1`。例如，以下代码获取字符串中索引 9 处的字符：

```
String anotherPalindrome = "Niagara. O roar again!"; 
char aChar = anotherPalindrome.charAt(9);

```

索引从 0 开始，因此索引 9 处的字符为“O”，如下图所示：

<center>![Use the charAt method to get a character at a particular index.](img/04b5f0416ca38f60591dfcd297bc80fc.jpg)</center>

如果要从字符串中获取多个连续字符，可以使用`substring`方法。 `substring`方法有两个版本，如下表所示：

<caption style="font-weight: bold">The `substring` Methods in the `String` Class</caption>
| 方法 | 描述 |
| --- | --- |
| `String substring(int beginIndex, int endIndex)` | 返回一个新字符串，该字符串是此字符串的子字符串。子字符串从指定的`beginIndex`开始，并扩展到索引`endIndex - 1`处的字符。 |
| `String substring(int beginIndex)` | 返回一个新字符串，该字符串是此字符串的子字符串。 integer 参数指定第一个字符的索引。这里，返回的子字符串延伸到原始字符串的末尾。 |

以下代码从 Niagara palindrome 获取从索引 11 延伸到索引 15 的子字符串，但不包括索引 15，即“咆哮”一词：

```
String anotherPalindrome = "Niagara. O roar again!"; 
String roar = anotherPalindrome.substring(11, 15); 

```

<center>![Use the substring method to get part of a string.](img/c76ca5899d8c39cb8ba3db60eca48c48.jpg)</center>

## 操纵字符串的其他方法

以下是其他几种用于操作字符串的`String`方法：

<caption style="font-weight: bold">Other Methods in the `String` Class for Manipulating Strings</caption>
| 方法 | 描述 |
| --- | --- |
| `String[] split(String regex)`
`String[] split(String regex, int limit)` | 搜索由字符串参数（包含正则表达式）指定的匹配，并相应地将此字符串拆分为字符串数组。可选的整数参数指定返回数组的最大大小。正则表达式在标题为“正则表达式”的课程中介绍。 |
| `CharSequence subSequence(int beginIndex, int endIndex)` | 返回从`beginIndex`索引构造的新字符序列，直到`endIndex` - 1。 |
| `String trim()` | 返回此字符串的副本，其中删除了前导和尾随空格。 |
| `String toLowerCase（）
String toUpperCase（）` | 返回转换为小写或大写的此字符串的副本。如果不需要转换，则这些方法返回原始字符串。 |

## 在字符串中搜索字符和子字符串

以下是一些用于在字符串中查找字符或子字符串的其他`String`方法。 `String`类提供访问器方法，返回特定字符或子字符串的字符串中的位置：`indexOf()`和`lastIndexOf()`。 `indexOf()`方法从字符串的开头向前搜索，`lastIndexOf()`方法从字符串的末尾向后搜索。如果未找到字符或子字符串，`indexOf()`和`lastIndexOf()`将返回-1。

`String`类还提供搜索方法`contains`，如果字符串包含特定字符序列，则返回 true。当您只需要知道字符串包含字符序列时，请使用此方法，但精确位置并不重要。

下表描述了各种字符串搜索方法。

<caption style="font-weight: bold">The Search Methods in the `String` Class</caption>
| 方法 | 描述 |
| --- | --- |
| `int indexOf（int ch）
int lastIndexOf（int ch）` | 返回指定字符的第一个（最后一次）出现的索引。 |
| `int indexOf（int ch，int fromIndex）
int lastIndexOf（int ch，int fromIndex）` | 返回指定字符的第一个（最后一次）出现的索引，从指定的索引向前（向后）搜索。 |
| `int indexOf（String str）
int lastIndexOf（String str）` | 返回指定子字符串的第一个（最后一次）出现的索引。 |
| `int indexOf（String str，int fromIndex）
int lastIndexOf（String str，int fromIndex）` | 返回指定子字符串的第一个（最后一次）出现的索引，从指定的索引向前（向后）搜索。 |
| `boolean contains(CharSequence s)` | 如果字符串包含指定的字符序列，则返回 true。 |

* * *

**Note:** `CharSequence` is an interface that is implemented by the `String` class. Therefore, you can use a string as an argument for the `contains()` method.

* * *

## 将字符和子字符串替换为字符串

`String`类只有很少的方法可以将字符或子串插入到字符串中。通常，它们不是必需的：您可以通过连接从中删除的子字符串来创建一个新字符串，该字符串包含您要插入的子字符串。

然而，`String`类确实有四种 _ 替换 _ 找到的字符或子串的方法。他们是：

<caption style="font-weight: bold">Methods in the `String` Class for Manipulating Strings</caption>
| 方法 | 描述 |
| --- | --- |
| `String replace(char oldChar, char newChar)` | 返回一个新字符串，该字符串是使用 newChar 替换此字符串中出现的所有 oldChar。 |
| `String replace(CharSequence target, CharSequence replacement)` | 将与该文字目标序列匹配的此字符串的每个子字符串替换为指定的文字替换序列。 |
| `String replaceAll(String regex, String replacement)` | 将给定替换的给定正则表达式匹配的此字符串的每个子字符串替换。 |
| `String replaceFirst(String regex, String replacement)` | 将给定替换的给定正则表达式匹配的此字符串的第一个子字符串替换。 |

## 一个例子

以下类 [`Filename`](examples/Filename.java) 说明了使用`lastIndexOf()`和`substring()`隔离文件名的不同部分。

* * *

**Note:** The methods in the following `Filename` class don't do any error checking and assume that their argument contains a full directory path and a filename with an extension. If these methods were production code, they would verify that their arguments were properly constructed.

* * *

```
public class Filename {
    private String fullPath;
    private char pathSeparator, 
                 extensionSeparator;

    public Filename(String str, char sep, char ext) {
        fullPath = str;
        pathSeparator = sep;
        extensionSeparator = ext;
    }

    public String extension() {
        int dot = fullPath.lastIndexOf(extensionSeparator);
        return fullPath.substring(dot + 1);
    }

    // gets filename without extension
    public String filename() {
        int dot = fullPath.lastIndexOf(extensionSeparator);
        int sep = fullPath.lastIndexOf(pathSeparator);
        return fullPath.substring(sep + 1, dot);
    }

    public String path() {
        int sep = fullPath.lastIndexOf(pathSeparator);
        return fullPath.substring(0, sep);
    }
}

```

这是一个程序 [`FilenameDemo`](examples/FilenameDemo.java) ，它构造一个`Filename`对象并调用它的所有方法：

```
public class FilenameDemo {
    public static void main(String[] args) {
        final String FPATH = "/home/user/index.html";
        Filename myHomePage = new Filename(FPATH, '/', '.');
        System.out.println("Extension = " + myHomePage.extension());
        System.out.println("Filename = " + myHomePage.filename());
        System.out.println("Path = " + myHomePage.path());
    }
}

```

以下是该计划的输出：

```
Extension = html
Filename = index
Path = /home/user

```

如下图所示，我们的`extension`方法使用`lastIndexOf`来定位文件名中最后一次出现的句点（。）。然后`substring`使用`lastIndexOf`的返回值来提取文件扩展名 - 即从字符串的句点到结尾的子字符串。此代码假定文件名中包含句点;如果文件名没有句点，`lastIndexOf`返回-1，子串方法抛出`StringIndexOutOfBoundsException`。

<center>![The use of lastIndexOf and substring in the extension method in the Filename class.](img/ae33969ba05d1d9c42d6975db70ee446.jpg)</center>

另请注意，`extension`方法使用`dot + 1`作为`substring`的参数。如果句点字符（。）是字符串的最后一个字符，则`dot + 1`等于字符串的长度，该字符串大于字符串中的最大索引（因为索引从 0 开始）。这是`substring`的合法参数，因为该方法接受的索引等于但不大于字符串的长度，并将其解释为“字符串的结尾”。