【问题标题】:Deleting all regex instances starting with char '[' and ending with char ']' from a String从字符串中删除所有以 char '[' 开头并以 char ']' 结尾的正则表达式实例
【发布时间】:2016-07-08 06:20:34
【问题描述】:

我需要获取String 并删除其中以character '[' 开头并以character ']' 结尾的所有正则表达式。

现在我不知道如何解决这个问题。我尝试将String 转换为字符数组,然后将空字符从任何开始的'[' 到他的结束']' 中,然后使用toString() 方法将其转换回String

我的代码:

char[] lyricsArray = lyricsParagraphElements.get(1).text().toCharArray();
                for (int i = 0;i < lyricsArray.length;i++)
                {
                    if (lyricsArray[i] == '[')
                    {
                        lyricsArray[i] = ' ';
                        for (int j = i + 1;j < lyricsArray.length;j++)
                        {
                            if (lyricsArray[j] == ']')
                            {
                                lyricsArray[j] = ' ';
                                i = j + 1;
                                break;
                            }
                            lyricsArray[j] = ' ';
                        }   
                    }
                }
                String songLyrics = lyricsArray.toString();
                System.out.println(songLyrics);

但是在 songLyrics 的印刷行中,我得到了一些奇怪的东西,比如

[C@71bc1ae4
[C@6ed3ef1
[C@2437c6dc
[C@1f89ab83
[C@e73f9ac
[C@61064425
[C@7b1d7fff
[C@299a06ac
[C@383534aa
[C@6bc168e5

我想有一个简单的方法。任何帮助将不胜感激。

为了澄清: 将"abcd[dsadsadsa]efg[adf%@1]d" 转换为"abcdefgd"

【问题讨论】:

标签: java arrays regex string tostring


【解决方案1】:

或者简单地使用正则表达式来replace all 出现\\[.*\\] 而没有任何内容:

String songLyrics = text.replaceAll("\\[.*?\\]", "");

text 当然是在哪里:

String text = lyricsParagraphElements.get(1).text();

\\[.*\\] 是什么意思?

replaceAll的第一个参数是一个描述正则表达式的字符串。正则表达式定义了一个匹配字符串的模式。

所以让我们分开:

\\[ 与字符 [ 完全匹配。由于[ 在正则表达式中有special meaning,因此需要对其进行转义(两次!)。

. 匹配任何字符,将其与 (lazy) 零或多个运算符 *? 结合,它将匹配任何字符,直到最终找到:

\\],匹配字符]。再次注意转义。

【讨论】:

  • 你能解释一下第一个参数\\[.\\]是什么意思吗?
  • 鉴于示例输入/输出,您应该使用 ? .*上的量词。
  • @AndyTurner 请解释一下。
  • @Tim 贪婪匹配将abcd[dsadsadsa]efg[adf%@1]d 更改为abcdd,而不是所需的输出。
  • @Tim 没关系。我的代码太大太复杂。但我得到了我想要的,这才是最重要的。再次感谢。
【解决方案2】:

下面的代码引用字符串对象,然后打印引用 songLyrics

String songLyrics = lyricsArray.toString();
System.out.println(songLyrics);

将上面两行替换为

String songLyrics = new String(lyricsArray);
System.out.println(songLyrics);

Ideone1

不将其转换为 char 数组并再次转换为字符串的其他方式。

String lyricsParagraphElements = "asdasd[asd]";

String songLyrics = lyricsParagraphElements.replaceAll("\\[.*\\]", "");

System.out.println(songLyrics);

Ideone2

【讨论】:

  • 是的。那挺好的。但是确实有必要将String 转换为字符数组,然后删除然后再转换回来。 java里有没有可以一行行的方法?就像有人建议的 ` LyricsParagraphElements.get(1).text().replaceAll("[\[\]]", " ")`??
  • @FallAndLearn 克隆我的答案几乎没有必要。它甚至不正确:lyricsParagraphElements 不是 String 类型。
  • @Tim 嗨。我没有复制你的答案。事实上,我是第一个发帖的,然后他问了另一种方式。 replaceAll() 方法是解决上述问题最简单简洁的方法。
  • @FallAndLearn 您在我之后 4 分钟内编辑的内容。无论如何,这是不正确的。
  • @Tim 你是对的。 replaceAll("\\[.*\\]", ""); 不起作用。
【解决方案3】:

您正在打印char[],而Java char[] 不会覆盖toString()。而且,Java String不可变的,但Java 确实有StringBuilder,它是可变的(并且StringBuilder.delete(int, int) 可以删除任意子字符串)。你可以像这样使用它,

String songLyrics = lyricsParagraphElements.get(1).text();
StringBuilder sb = new StringBuilder(songLyrics);
int p = 0;
while ((p = sb.indexOf("[", p)) >= 0) {
    int e = sb.indexOf("]", p + 1);
    if (e > p) {
        sb.delete(p, e + 1);
    }
    p++;
}
System.out.println(sb);

【讨论】:

    【解决方案4】:

    您得到了“奇怪的东西”,因为您正在打印数组的字符串表示形式,而不是将数组转换为字符串。

    lyricsArray.toString()代替

    new String(lyricsArray);
    

    但是如果你这样做,你会发现你实际上并没有从字符串中删除字符,只是用空格替换它们。

    相反,您可以将数组中的所有字符向左移动,并构造新的字符串,直到正确的字符数:

    int src = 0, dst = 0;
    while (src < lyricsArray.length) {
      while (src < lyricsArray.length && lyricsArray[src] != '[') {
        lyricsArray[dst++] = lyricsArray[src++];
      }
      if (src < lyricsArray.length) {
        ++src;
        while (src - 1 < lyricsArray.length && lyricsArray[src - 1] != ']') {
          src++;
        }
      }
    }
    String lyricsString = new String(lyricsArray, 0, dst);
    

    【讨论】:

      【解决方案5】:

      这正是您的情况的正则表达式字符串:

      \\[([\\w\\%\\@]+)\\]
      

      当您的植物字符串包含特殊符号时,这非常困难。我找不到更短的正则表达式,没有解释特殊符号(如异常)。 参考:https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#cg

      =================

      我正在阅读您的新案例,一个包含符号“-”或其他内容的字符串 !"#$%&'()*+,-./:;?@\^_`{|}~ 在我的正则表达式字符串的 \\@ 之后添加它们(带有前缀“\\”)。

      【讨论】:

      • 所以将String songLyrics = text.replaceAll("\\[.*?\\]", ""); 更改为String songLyrics = text.replaceAll("\[([\w\%\@]+)\]", "");?会让它完美吗?因为Eclipse 说它是无效的转义序列。
      • @God:我不知道为什么,当 \\ (两个反斜杠)被重新标记为 \ (一个反斜杠)时。我已经纠正了。请记住它始终是 \\,而不是 \。
      • @God:我认为 stackoverflow 通过自动将 2 个反斜杠替换为 1 个反斜杠让我感到困惑。试试我在代码标签中引用的字符串并享受。
      猜你喜欢
      • 2019-07-20
      • 2015-07-20
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-07
      相关资源
      最近更新 更多