2012-04-25 2 views
52

FooBarからFoo_Barのような文字列を正規表現を使用して変換すると、なぜ出力が得られないのか理解していますが、代わりにFoo_Bar_となります。私はString.substring substring(0, string.length() - 2)で何かをやったことができたか、最後の文字を置き換えてしまったかもしれませんが、私はそのようなシナリオに対してはより良い解決策があると思います。ここでCamelCaseをjavaでcamel_caseに変換する正規表現

はコードです:

String regex = "([A-Z][a-z]+)"; 
String replacement = "$1_"; 

"CamelCaseToSomethingElse".replaceAll(regex, replacement); 

/* 
outputs: Camel_Case_To_Something_Else_ 
desired output: Camel_Case_To_Something_Else 
*/ 

質問:所望の出力を得るために滑らかな印象方法をお探しですか?

+0

この質問は、http:// stackoverflowと似ています。com/questions/4886091/insert-space-after-capital-letter –

答えて

99

は何かのように、あなたのケースで、このquestionCaseFormat from guava

を参照してください。肯定的な先読みでは、大文字で始まり小文字に続く別の単語が検索されますが、一致には含まれません。ここ

ルック:http://regexr.com?30ooo

+0

@eliocs質問はアンドロイドと "ちょっと"とタグ付けされていませんでした..とにかくdownvoteに感謝;) –

+1

CaseFormatリンクはオフラインです。置換は[こちら](https://github.com/google/guava/blob/master/guava/src/com/google/common/base/CaseFormat.java) – Anticom

+0

@Anticom、編集済みです。ありがとう:) –

2

ゼロ幅先読みアサーションを追加します。個人的に

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

(?=X)のドキュメントを読むなど

、私は実際には、それを再結合し、文字列を分割します。これは正しく実行されるとさらに高速になり、正規表現の魔法よりもはるかに理解しやすいコードになります。私を間違えないでください:私は正規表現が大好きです。しかし、これは実際にはきちんとした正規表現ではなく、変換は古典的な正規表現タスクでもありません。結局のところ、あなたは小文字も使いたいと思われますか? (あなたが直接交換を小文字ことができますPerlスタイルextrended正規表現を行うことができない限り!)

醜いが、迅速なハックは$1_$2(.)([A-Z]+)を交換することで、その後、その後、文字列全体を小文字でしょう。それでも、私は下から上への遷移で分割し、変換し、次にこれを行うための適切で最も読みやすい方法として参加することを検討します。

CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "SomeInput"); 
+0

はい、結局は小文字にしたいと思います。 – ajmartin

+0

だから、 '[A-Z] [a-z] *'にマッチした小塊に分割し、最初の文字を小文字にして再結合します。または、置換+小文字のトリックをメイン返信に追加しました。 –

1
([A-Z][a-z\d]+)(?=([A-Z][a-z\d]+)) 

は、小文字に続いて大文字を検索する必要があります

46

が2グループとして下ケースと上ケースと結合し、それはあなたがコードスニペットの下に使用することができます

public class Main 
{ 
    public static void main(String args[]) 
    { 
     String regex = "([a-z])([A-Z]+)"; 
     String replacement = "$1_$2"; 
     System.out.println("CamelCaseToSomethingElse" 
          .replaceAll(regex, replacement) 
          .toLowerCase()); 
    } 
} 
22

OKになります。

String replaceAll = key.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase(); 
+0

スリックAF。うまくやった! –

+0

文字列に数値が含まれているとどうなりますか?mode3はmode3になりますが、mode3は必要です。 –

3

なぜありません前の文字を単に行の先頭でないものとして一致させるだけです$

String text = "CamelCaseToSomethingElse"; 
System.out.println(text.replaceAll("([^_A-Z])([A-Z])", "$1_$2")); 

このバージョンは、既にラクダ化されているものに対しては安全に実行できます。

+0

'^'と '$'をアンカーとして使用しようとしていますか?あなたがそれらを文字クラスに入れると、その意味が変わるからです。 '[^ $ _A-Z]'は、 '$'、 '_'、大文字でない文字にマッチします。 –

+0

アンカーとして意図していません。上の文字と一致しないようにしようとしていますが、 '$ 'はクラス名に使用する手法であるため誤って追加されました。 –

0
public class ReplaceFromCameltoSnake { 
    public static void main(String args[]){ 
     String s1=" totalAmountWithoutDiscount"; 
     String replaceString=s1.replaceAll("([A-Z]+)","\\_$1").toLowerCase(); 
     System.out.println(replaceString); 
    } 
} 
+0

$ 1 - グループの作成に使用されます –

+0

説明を追加するだけでコードを投稿しないでください。 – reformed