2009-07-08 25 views
3

これはシンプルなようですが、うまく動作しません。文字列の一部を空白で置き換える正規表現

「NNDDDDDAAAA」のような文字列があります。「N」は非数字、「D」は数字、「A」は何でもあります。私は各Aをスペース文字で置き換える必要があります。入力文字列中の 'N'、 'D' s、 'A'の数は常に異なっています。

私は2つの表現でそれを行う方法を知っています。文字列を2つに分割し、2番目のグループのすべてをスペースで置き換えることができます。このように

しかし、私はそれが単一の正規表現で可能かどうか疑問に思っていました。

+2

「A」と「A」の違いを教えてください。 Do 'Aはいつも' D 'の後に来ますか? – BryanH

+1

最後の "D"と最初の "A"の違いはどうやって分かりますか? "A"のグループは "D"タイプの文字ではないことが保証されていますか? –

+0

Curtis Taskerは正しいです、NNDDDDの後の最初のAは常にNです。残りは何でもあります。 –

答えて

0

私はあなたが正規表現を求め知っているが、なぜあなたも、このための正規表現が必要なのでしょうか?方法:

StringBuilder sb = new StringBuilder(inputString); 
for (int i = sb.length() - 1; i >= 0; i--) { 
    if (Character.isDigit(sb.charAt(i))) 
     break; 
    sb.setCharAt(i, ' '); 
} 
String output = sb.toString(); 

this postが面白いかもしれません。もちろん、上のコードでは、文字列に少なくとも1桁の数字があることを前提としています。最後の桁に続くすべての文字はスペースに変換されます。数字がない場合は、すべての文字がスペースに変換されます。

+0

あなたは正しいと思います。 私は複数のループとindexOf()/ substring()を持つ古いコードをリファクタリングしていましたが、単純な正規表現で行うことができると思いました。古い論理を掃除することについても考えなかった。私はあなたのアプローチがこの作業のために最も効率的だと思います。 箱の外で考えていただき、ありがとうございました。 –

+0

あなたのコードでは、AAAの部分は数字ではないと想定しています。これは、Aが数字を含む「何か」となるという問題の記述に反する。 –

+0

それでは、解決策は、桁の後に桁がない桁を見つけるためにわずかに適合させることができます。それは本当に必要ではない正規表現を使用するより簡単です。 –

1

何もないのは何ですか?

[^a-zA-Z0-9]
ない文字または数字であるすべてのものと一致しました。

上記の正規表現と一致するものをスペースで置き換えたいとします。

これはあなたが話していたものですか?

+0

/[^ a-zA-Z0-9]// gという意味じゃないの? – BryanH

+0

これは "anything"のマッチを削除するだけで、実際に "anything"にマッチする正規表現をスローしたいと思っています。ありがとう。 –

+0

「何か」とは何か、つまり文字、数字、空白を意味します。 各オカレンスをスペースで置き換えてください。たとえば、「AA12345d4%」は「AA12345」(最後は4つのスペース)に置き換えられます –

1

あなたはNとDを一致させるために肯定的な裏返しを使い、次にAに対して通常のマッチを使用したいと思う。

ないJavaの文法の背後にある正見て、しかし、あなたの説明が与えられJava regex with look behind

+0

私はちょうどそのことを投稿しようとしていました...正直!たとえば、(?<= \ D +) –

+0

Java正規表現について:私はいくつかの記事を読んで、先読み/後ろ向きの制限についての話を読んだことがあります正規表現エンジンの3つの主要な変種と私が持っていた主な奪い取りは、.Netの正規表現が良いものをすることができたが、時にはそれができるという理由だけではないことがあります。 –

+0

さまざまなエンジンの背後を見るためのサポートについての素晴らしい説明があります:http://www.regular-expressions.info/lookaround.html#limitbehind – laz

3

上のいくつかの記事を確認してください、私はNNDDDDD部分の後、最初Aが実際にNいうよりAになることを想定していますそうでなければ、DDDDDAAAA部分の間には堅実な境界がないからです。

実際には文字列はNNDDDDDNAAAのようになり、NAAA部分をスペースで置き換えます。これを仮定すると、正規表現は次のように書き直すことができます。(\\D+\\d+)(\\D.+)

Javaの正のlookbehindには固定長のパターンが必要です。 +または*パターンは使用できません。代わりに、中括弧を使用して、最大長を指定することもできます。たとえば、あなたは、各+の代わりに{1,9}を使用することができ、それは1〜9の文字にマッチします:(?<=\\D{1,9}\\d{1,9})(\\D.+)

ここでの唯一の問題はあなたがそうなります​​を使用して、単一のマッチとしてNAAAシーケンスにマッチしていていますNAAAシーケンス全体を複数のスペースではなく単一のスペースで置き換えることができます。

マッチの開始区切り文字と文字列の長さを使用して、それを使って正しいスペース数を追加できますが、その点は表示されません。私はあなたが元のソリューションで一層良いと思う。そのシンプルで簡単に従うこと。

速度を少し上げたい場合は、関数の外でパターンをコンパイルし、StringBuilderまたはStringBufferを使用して出力を作成できます。これらのすべてのNNDDDDDAAAAA要素から大きなStringを構築する場合は、追加が完了するまでStringBuilderで完全に作業します。

class Test { 

public static Pattern p = Pattern.compile("(\\D+\\d+)(\\D.+)"); 

public static StringBuffer replace(String input) { 
    StringBuffer output = new StringBuffer(); 
    Matcher m = Test.p.matcher(input); 
    if(m.matches()) 
     output.append(m.group(1)).append(m.group(2).replaceAll("."," ")); 

    return output; 
} 

public static void main(String[] args) { 
    String input = args[0]; 
    long startTime; 

    StringBuffer tests = new StringBuffer(); 
    startTime = System.currentTimeMillis(); 
     for(int i = 0; i < 50; i++) 
     { 
      tests.append("Input -> Output: '"); 
      tests.append(input); 
      tests.append("' -> '"); 
      tests.append(Test.replace(input)); 
      tests.append("'\n"); 
     } 
    System.out.println(tests.toString()); 
    System.out.println("\n" + (System.currentTimeMillis()-startTime)); 
} 

} 

更新: 私は、迅速な反復解法を書いた、との両方を通じて、いくつかのランダムなデータを走りました。反復解は約4〜5倍高速です。

public static StringBuffer replace(String input) 
{ 
    StringBuffer output = new StringBuffer(); 
    boolean second = false, third = false; 
    for(int i = 0; i < input.length(); i++) 
    { 
     if(!second && Character.isDigit(input.charAt(i))) 
      second = true; 

     if(second && !third && Character.isLetter(input.charAt(i))) 
      third = true; 

     if(second && third) 
      output.append(' '); 
     else 
      output.append(input.charAt(i)); 

    } 

    return output; 
} 
関連する問題