给定一个字符串,在第 50 位插入一个新的换行符并排除整个单词


String str = "Hello how are you today music fine.This is a new line"
String parsedStr = str.replace("(.{50})","$1n");

我需要字符串新字符串

Hello how are you today music fine.This is a new 
line

但我是这样的

Hello how are you today music fine.This is a new l
ine

我遇到了单词边界(\b(。尝试过,但不适用于我的情况。

使用每行要使用的字符数构造正则表达式子句.{1,N}
就像 50 一样,这将是.{1,50}.

压缩

查找:(?:(?:(?>(.{1,50})(?:(?<=[^Srn])[^Srn]?|(?<=[,.;:!/?])[^Srn]?|(?=r?n|[-#%&*@_])|[^Srn]))|(.{1,50}))(?:r?n)?|(?:r?n))

替换:$1$2rn

(?:
# -- Words/Characters 
(?:
(?>                           # Atomic Group - Match words with valid breaks
( .{1,50} )                   # (1), 1-N characters
#  Followed by one of 4 prioritized, non-linebreak whitespace
(?:                           #  break types:
(?<= [^Srn] )              # 1. - Behind a non-linebreak whitespace
[^Srn]?                    #      ( optionally accept an extra non-linebreak whitespace )
|  (?<= [,.;:!/?] )              # 2. - Behind sepcial punctuation breaks
[^Srn]?                    #      ( optionally accept an extra non-linebreak whitespace )
|  (?=                           # 3. - Ahead a linebreak or special punctuation breaks
r? n 
|  [-#%&*@_] 
)
|  [^Srn]                     # 4. - Accept an extra non-linebreak whitespace
)
)                             # End atomic group
|  
( .{1,50} )                   # (2), No valid word breaks, just break on the N'th character
)
(?: r? n )?                 # Optional linebreak after Words/Characters
|  
# -- Or, Linebreak
(?: r? n )                  # Stand alone linebreak
)

很可能有一个简单的解决方案来解决你的问题。鉴于 OP 如何仅为我们提供一个示例字符串,不确定是否有任何特殊情况,但以下内容适用于他们的示例字符串。

注意:我正在发布原始正则表达式。您需要在 Java 中转义所有必要的字符(反斜杠(。

选项 1

您甚至可以使用^(.{0,50})(末尾有一个空格(而不是b.

在此处查看正在使用的正则表达式

^(.{0,50}b)
  • ^在行首断言位置
  • (.{0,50}b)捕获任何字符最多 50 次,断言结束位置与捕获组 1b的单词边界匹配

替换:$1n

结果:

Hello how are you today music fine.This is a new 
line

选项 2

此方法使用选项 1 作为基础,但为字符串添加逻辑,该字符串可能会在标点符号之前添加n(这可能是意外结果(。对于这些情况,您可以使用以下内容。

在此处查看正在使用的正则表达式

^(.{0,50}b(?!p{P}|$))
  • 逻辑与选项 1 相同,但确保b与字符串的末尾不匹配p{p}(标点字符(或结尾。

结果(第二个选项在使用选项 1 的正则表达式.之前必须n(:

Hello how are you today music fine.This is a new 
line
This line contains 50 characters to show dot 
issue.Some other string here

试试这段代码:

String str = "Hello how are you today music fine.This is a new line"
int index = 50;
while(str.getCharAt(index) != ' ') 
{
index--;
}
String parsedStr = str.replace("(.{index})","$1n");

这确实可以满足您的要求,仅此而已。但是,如果您真的想实现自动换行,那么这不是一个好方法。

String str = "Hello how are you today music fine.This is a new line";
String parsedStr = str.replaceFirst("^(.*?)\s*((\S(?!\s))*(?<=.{50}).*$)",
"$1"+System.lineSeparator()+"$2");
String [] pieces = parsedStr.split(System.lineSeparator());
for(String piece : pieces ) {
System.out.format("length %2d: "%s"%n", piece.length(), piece);
}

输出:

第48章:"你好,你今天好吗。这是一个新的">

长度4:"线">

解释:

  • ^ =行首(开始组 1(
  • .*? =勉强匹配任意数量的字符(结束组 1(
  • s* =消耗行将拆分的所有空格(开始组 2(
  • S* =匹配任意数量的非空格字符...
  • (?!\s) =后面没有空格,否则我们会错过正好 50 的拆分机会
  • (?<=.{50}) =正好 50 个字符的正面回顾
  • .*$ =包括行中的所有剩余字符(结束组 2(
<小时 />

更简单的选择:

使用这个更简单的正则表达式,您可以获得非常相似的结果:

String parsedStr = str.replaceFirst("^(.{0,50})\s+",
"$1"+System.lineSeparator());

(类似的建议归功于CTWHEELS(

唯一的区别是,如果在拆分之前有多个空格,则在第 1 行的末尾可能会有一些额外的空格。但这不是一件坏事。

最新更新