JAVA:反转字符串时删除分隔符

huangapple go评论81阅读模式
英文:

JAVA: Delimiter removed when reversing a string

问题

如何在下面的代码中,在将字符串反转时包含分隔符?

Pattern.compile(Pattern.quote("."))
       .splitAsStream("BCTVW.")
       .map(s->new StringBuilder(s).reverse())
       .collect(Collectors.joining("."))

当前输出:WVTCB.
期望输出:.WVTCB

期望输出中缺少了分隔符。

英文:

How can I include the delimiter when reversing my string via code below?

Pattern.compile(Pattern.quote("."))
       .splitAsStream("BCTVW.")
       .map(s->new StringBuilder(s).reverse())
       .collect(Collectors.joining("."))

Current output: WVTCB.
Desired output: .WVTCB

The delimiter is missing from the desired output.

答案1

得分: 1

你可以使用非捕获组,例如前瞻。

Pattern.compile("(?<=\\.)")
             .splitAsStream("BCTVW.")
             .map(s->new StringBuilder(s).reverse())
             .collect(Collectors.joining("."));
英文:

You can use non-capturing groups, e.g. lookahead.

Pattern.compile(&quot;(?&lt;=\\.)&quot;)
             .splitAsStream(&quot;BCTVW.&quot;)
             .map(s-&gt;new StringBuilder(s).reverse())
             .collect(Collectors.joining(&quot;.&quot;));

答案2

得分: 1

Pattern(regex).splitAsStream(data)具有与data.split(regex)类似的功能,因此它也会删除作为分割结果而创建的尾随空字符串

例如,&quot;a,b,&quot;.split(&quot;,&quot;) 不会导致[&quot;a&quot;,&quot;b&quot;,&quot;&quot;],而是[&quot;a&quot;,&quot;b&quot;],因为数组末尾的空字符串会被删除。

Pattern#splitAsStreamString#split之间最关键的区别是String#split(regex)方法具有重载版本String#split(regex, limit),其中limit的值会影响其结果。

如果limit为:

  • 正数,它会设置结果数组中的最大元素数量,例如&quot;a,b,c,d&quot;.split(&quot;,&quot;, 3)会得到[&quot;a&quot;, &quot;b&quot;, &quot;c,d&quot;]
  • 0,它会导致删除尾随的空字符串(split(regex,0)split(regex)相同)。
  • 负数 - 阻止split删除尾随的空字符串 - 这是您想要的效果。

因此,不要使用Pattern#splitAsStream,而是使用您在先前问题中尝试过的String#split方法:

> 引用以防先前的问题被移除
> &gt; String fileContent = &quot;Abc.134dsq&quot;; &gt; String delimiter = &quot;.&quot;; &gt; fileContent = fileContent.replace(delimiter, &quot;-&quot;); &gt; String[] splitWords = fileContent.split(&quot;-&quot;); &gt; StringBuilder stringBuilder = new StringBuilder(); &gt; for (String word : splitWords) { &gt; StringBuilder output = new StringBuilder(word).reverse(); &gt; stringBuilder.append(output); &gt; } &gt; &gt; System.out.println(stringBuilder.toString()); &gt;

您需要纠正的问题:

  1. 不要将字符串中的delimiter替换为-以便在-上分割,因为您的字符串可能包含自己的-。例如,将.替换为-之后,&quot;A.B-C&quot;将变为A-B-C,这将导致不需要的B-C分割。

    而是使用Pattern.quote(delimiter)进行分割 - 就像您在当前问题中提供的示例中所做的那样。

  2. 使用带有负限制参数的split,以防止删除尾随的空字符串(类似于fileContent.split(Pattern(delimiter), -1))。

  3. 您没有将分隔符添加回结果字符串。一个简单的解决方案是使用StringJoiner joiner = new StringJoiner(delimiter); joiner.add(reversedElement),而不是使用StringBuilder,因为joiner.add还会处理我们要连接的元素之间的分隔符添加。

英文:

Pattern(regex).splitAsStream(data) has similar functionality as data.split(regex) so it also removes trailing empty strings created as result of splitting.
For instance &quot;a,b,&quot;.split(&quot;,&quot;) would NOT result in [&quot;a&quot;,&quot;b&quot;,&quot;&quot;] but [&quot;a&quot;,&quot;b&quot;] because empty strings at the end of array would be removed.

Most crucial difference between Pattern#splitAsStream and String#split is that String#split(regex) method has overloaded version String#split(regex, limit) where limit depending on value affects its result.

If limit is

  • positive it sets maximal amount of elements in resulting array like &quot;a,b,c,d&quot;.split(&quot;,&quot;, 3) would result in [&quot;a&quot;, &quot;b&quot;, &quot;c,d&quot;].
  • 0 it causes removal of trailing empty strings (split(regex,0) is same as split(regex)
  • negative - prevents split from removing trailing empty strings - this is what you are after.

So don't use Pattern#splitAsStream but instead String#split method like you tried in your previous question:

> quotation in case previous question would be removed
> &gt; String fileContent = &quot;Abc.134dsq&quot;; &gt; String delimiter = &quot;.&quot;; &gt; fileContent = fileContent.replace(delimiter, &quot;-&quot;); &gt; String[] splitWords = fileContent.split(&quot;-&quot;); &gt; StringBuilder stringBuilder = new StringBuilder(); &gt; for (String word : splitWords) { &gt; StringBuilder output = new StringBuilder(word).reverse(); &gt; stringBuilder.append(output); &gt; } &gt; &gt; System.out.println(stringBuilder.toString()); &gt;

Things you need to correct there:

  1. DONT replace delimiter in your string to - to split on - because your string may contain its own -. For instance &quot;A.B-C&quot; after replacing . to - will become A-B-C which will result in unwanted splitting B-C.

    Instead split using Pattern.quote(delimiter) - like you did in example provided in current question.

  2. Use split with negative limit parameter to prevent removing trailing empty strings (something like fileContent.split(Pattern(delimiter), -1))

  3. You are not adding delimiters back to resulting string. Easy solution would be using StringJoiner joiner = new StringJoiner(delimiter); joiner.add(reversedElement) instead of StringBuilder because joiner.add will also handle adding delimiter between elements we want to join.

huangapple
  • 本文由 发表于 2020年4月4日 08:33:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/61022360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定