在Java中,给定多行
String
我想获取从开头到第n行的子字符串以及该行上的字符索引。 (行索引和字符索引都是从零开始的。)
例如,如果我们要实现这样的方法:
/**
* Returns the substring of the given string up to the given character index on the given line index.
*
* @param text input text
* @param line line index
* @param character character index
* @return substring
*/
public static String substring(String text, int line, int character);
然后,考虑以下多行字符串:
对于给定的输入,上述方法应该返回你好
世界
你好吗
你好吗?
他
你好工作
你好我考虑了几种方法:世界
如何
String
进行操作直至第 n 行来构造子字符串:一种方法是使用
string.lines()
,并构建子字符串。
像这样的东西:
public static String buildSubstring(String text, int line, int character) {
long textLines = text.lines().limit(line + 1).count();
StringBuilder builder = new StringBuilder();
int lineCount = 0;
for (Iterator<String> iter = text.lines().limit(line + 1).iterator(); iter.hasNext(); ) {
String lineText = iter.next();
if (line == lineCount) {
builder.append(lineText, 0, Math.min(character, lineText.length()));
} else {
builder.append(lineText);
}
if (line < textLines) {
builder.append(System.lineSeparator());
}
lineCount++;
}
return builder.toString();
}
但是,我主要担心的是过多的字符串创建对性能的影响。
string.substring(0, x)
,其中 x 是字符索引 - 在原始多行 String
中 - 第 n 行以及该行中的位置。但是,我不清楚在原始字符串中查找字符索引的最佳方法是什么。
string.indexOf(System.lineSeparator(),lineIndex)
来识别原始字符串中该行的位置,并在该行上添加字符索引。像这样的东西:
public static String indexSubstring(String text, int line, int character) {
String separator = System.lineSeparator();
int separatorLength = separator.length();
int lineIndex = 0;
if (line > 0) {
lineIndex = text.indexOf(separator) + separatorLength;
for (int i = 1; i < line; i++) {
lineIndex = text.indexOf(separator, lineIndex) + separatorLength;
}
}
return text.substring(0, lineIndex + character);
}
但是,如果文本中的行分隔符与 System.lineSeparator()
不同,这将无法处理情况;我的情况就是这种情况 - 也就是说,原始文本可能来自 UNIX 或 Windows 环境和/或此功能可能在 UNIX 或 Windows 环境上执行,并且它们需要可互操作。当然,人们可以做一个
string.replaceAll("\\r?\\n, System.lineSeparator())
,但是与第一种使用
String
的方法相比,这会产生更多的
string.lines()
创建。注意:就这个问题而言,我不处理错误情况 - 例如,行/字符索引超出原始
String
的长度,或者字符索引超出线。一旦我决定了基本方法,这些将在稍后考虑;或者,为了简单起见,我们可以假设它将返回该行或输入文本中的所有内容。问题:
String
中第n行的字符位置以及该行的字符索引?即用于 string.substring(0, x)。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String text = """
hello
world
how
are
you?""";
System.out.println(substring(text, 0, 2)); // he
System.out.println(substring(text, 1, 3)); // hello\nwor
System.out.println(substring(text, 3, 0)); // hello\nworld\nhow\n
try {
System.out.println(substring(text, 6, 0)); // Line index out of bounds
} catch (IndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
try {
System.out.println(substring(text, 0, 6)); // Range [0, 6) out of bounds for length 5
} catch (IndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
}
/**
* Returns the substring of the given string up to the given character index on the given line index.
*
* @param text input text
* @param line line index (starting at 0 for the first line)
* @param character character index (starting at 0 for the first character)
* @return substring
*/
public static String substring(String text, int line, int character) throws IndexOutOfBoundsException {
Scanner scanner = new Scanner(text);
int lineCount = 0;
StringBuilder sb = new StringBuilder();
while (scanner.hasNextLine()) {
String lineText = scanner.nextLine();
if (lineCount == line) {
sb.append(lineText, 0, character);
break;
} else {
sb.append(lineText);
sb.append(System.lineSeparator());
}
lineCount++;
}
if (lineCount < line) {
throw new IndexOutOfBoundsException("Line index out of bounds");
}
return sb.toString();
}
}