多行字符串的Java子字符串直到第n行以及该行的字符索引

问题描述 投票:0回答:1

在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);

然后,考虑以下多行字符串:

你好
世界
你好吗
你好吗?

对于给定的输入,上述方法应该返回

    子串(文本, 0, 2);

    子串(文本, 1, 3);
你好

工作

    子串(文本, 3, 0);
你好

世界
如何


我考虑了几种方法:

    通过对
  1. 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(); }
但是,我主要担心的是过多的字符串创建对性能的影响。

    获取原始字符串中直到字符索引的子字符串:
  1. 更直观的方法可能是使用
    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

 的长度,或者字符索引超出线。一旦我决定了基本方法,这些将在稍后考虑;或者,为了简单起见,我们可以假设它将返回该行或输入文本中的所有内容。

问题:

    如何获取多行
  1. String
    中第n行的字符位置以及该行的字符索引? 
    即用于 string.substring(0, x)。
  2. 有没有比我上面列出的方法更好的方法来获取子字符串?
java string substring multiline
1个回答
0
投票
使用现有的系统类和方法总是能让你走得更远,它们更高效,让你更精确地得到结果。

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(); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.