5

これらのような文字列があるとしましょう:

"abcdaaaaefghaaaaaaaaa"
"012003400000000"

これを取得するために、最後の繰り返し文字を削除したいと思います:

"abcdaaaaefgh"
"0120034"

正規表現を使用してこれを行う簡単な方法はありますか? 私はこれに苦労しており、私のコードは巨大なモンスターのように見え始めています...

明確化:

  • 反復的と見なされるものは何ですか?

    最後に少なくとも2文字のシーケンス。1 文字は繰り返しとは見なされません。たとえば、 in"aaaa"'a'反復的とは見なされませんが、 in は反復的"baaaa"です。の場合"aaaa"、文字列に何も変更する必要はありません。別のインスタンス:"baa"与える必要があります"b"

  • そして、1文字だけの文字列の場合は?

    "a"char のみを含む文字列 likeは'a'、何も変更せずに返す必要があります。つまり、 return にする必要があり"a"ます。

4

5 に答える 5

10

replaceAll()後方参照と一緒に 使用できます。

str = str.replaceAll("(.)\\1+$", "");

編集

文字列全体を削除できないという要件を満たすために、正規表現を過度に複雑にするのではなく、後でチェックを追加するだけです。

public String replaceLastRepeated(String str) {
    String replaced = str.replaceAll("(.)\\1+$", "");
    if (replaced.equals("")) {
        return str;
    }
    return replaced;
}
于 2013-04-02T13:24:44.390 に答える
3

私は正規表現を使用しません:

public class Test {
  public void test() {
    System.out.println(removeTrailingDupes("abcdaaaaefghaaaaaaaaa"));
    System.out.println(removeTrailingDupes("012003400000000"));
    System.out.println(removeTrailingDupes("0120034000000001"));
    System.out.println(removeTrailingDupes("cc"));
    System.out.println(removeTrailingDupes("c"));
  }

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return s.substring(0, cut);
    }
    // Return it untouched.
    return s;
  }

  public static void main(String args[]) {
    new Test().test();
  }
}

@JonSkeet の「仕様」に合わせるには:

これにより、最後に重複した文字のみが削除されることに注意してください。つまり、1 文字の文字列は変更されませんが、2 文字の文字列は両方の文字が同じ場合は空になる可能性があります。

"" => ""
"x" => "x"
"xx" => ""
"aaaa" => ""
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"

正規表現でそのレベルの制御を達成できるのだろうか?

...の結果として追加されましたが、たとえば aaaa でこの正規表現を使用すると、何も返されません。aaaa を返す必要があります。コメント:

代わりに、次を使用します。

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return cut > 0 ? s.substring(0, cut): s;
    }
    // Return it untouched.
    return s;
  }

契約を結んでいる:

"" => ""
"x" => "x"
"xx" => "xx"
"aaaa" => "aaaa"
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"
于 2013-04-02T13:32:23.623 に答える
3

これに正規表現を使用するとは思わない:

public static String removeRepeatedLastCharacter(String text) {
    if (text.length() == 0) {
        return text;
    }
    char lastCharacter = text.charAt(text.length() - 1);
    // Look backwards through the string until you find anything which isn't
    // the final character
    for (int i = text.length() - 2; i >= 0; i--) {
        if (text.charAt(i) != lastCharacter) {
            // Add one to *include* index i
            return text.substring(0, i + 1);
        }
    }
    // Looks like we had a string such as "1111111111111".
    return "";
}

個人的には、正規表現よりも理解しやすいと思います。速いかもしれないし、速くないかもしれません - 私は予測したくありません。

これは、繰り返されるかどうかにかかわらず、常に最後の文字を削除することに注意してください。つまり、単一の文字列は常に空の文字列になります。

"" => ""
"x" => ""
"xx" => ""
"ax" => "a"
"abcd" => "abc"
"abcdddd" => "abc"
于 2013-04-02T13:26:59.200 に答える
0

これでうまくいくはずです:

public class Remover {
     public static String removeTrailing(String toProcess)
     {
        char lastOne = toProcess.charAt(toProcess.length() - 1);
        return toProcess.replaceAll(lastOne + "+$", "");
     } 

     public static void main(String[] args)
     {
        String test1 = "abcdaaaaefghaaaaaaaaa";
        String test2 = "012003400000000";

        System.out.println("Test1 without trail : " + removeTrailing(test1));
        System.out.println("Test2 without trail : " + removeTrailing(test2));
     }
}
于 2013-04-02T13:36:07.920 に答える