2

文字列を文字列の配列に分割しようとしましたが、問題は.split()空の要素も返すことです。("test").split戻り["","t","e","s","t"]ます。

この質問の解決策Split string into array of character stringsを使用して問題を解決し.split("(?!^)")ます。

ただし、これが機能する理由はまだ理解できません。仕事が完了するという理由だけで理解できないコードを使用するつもりはありません。

これらの 2 つのページhttp://www.regular-expressions.info/lookaround.htmlhttp://ocpsoft.org/opensource/guide-to-regular-expressions-in-Java-part-2/について読みました否定的な先読みで、まだ理解できません。誰かがこれを明確にできますか?

4

3 に答える 3

5

を使用("test").split()すると、文字の前のすべての位置で文字列が分割され、結果は になります["", "t", "e", "s", "t"]。これは、最初の分割 ( の前t) でエントリが空になるためです。

この正規表現 ( "(?!^)") は次のことを意味します:すべての文字で文字列を分割します。ここで、行頭 (^) は前の文字ではありません*:

あなたの文字列は基本的に(正規表現エンジンの場合)次のようになります。^test$ したがって、正規表現は最初の前の分割を除いてすべての分割を実行します。これは、現在の位置の前の文字が -tに一致し、分割されるべきではないためです。 ^( ^String / Line-Start) です。

*実際に^は、これはキャラクターではありません。そのため、前に別の分割を行う必要はありません。つまり、$それらは単なるメタキャラクターです。

于 2013-10-21T19:46:39.370 に答える
2

最初に、返された配列に空の最初の要素が含まれている理由を理解する必要があります。index にある区切り文字で文字列を分割すると、0その区切り文字でも分割されます。区切り文字の左側は空の文字列になり0、配列のインデックスに格納されます。

したがって、次のコードは、最初の配列要素を空の文字列として指定します。

"#ab#c".split("#");  // ["", "ab", "c"]

ただし、#文字列の最初の文字ではない場合、インデックス 0 に空の文字列はありません。

ここで、空の文字列を最初の要素として使用したくない場合は、 first での分割を避ける必要があります#。どうやってそれをしますか?否定の後読みを使用して#、文字列 - の先頭にないことを確認してください。^

"#ab#c".split("(?<!^)#");  // ["ab", "c"]

#この正規表現は、文字列の先頭が前にない場合に分割されます(?<!^)^は文字列の先頭を示し、(?<!...)負の後読みを示します。


したがって、区切り文字自体が空の文字列になりました。文字列には、すべての文字の前と最後の文字の後にも空の文字列が含まれていることに注意してください。したがって、空の文字列で単純に分割すると、最初の文字の前にある区切り文字で分割されます。最初のものを除いて、空の文字列で分割する必要があります。#空の文字列に置き換える:

"abc".split("(?<!^)");  // ["a", "b", "c"]

同様に、否定的な先読みは機能します(?!^)が、IMO では、ここでは否定的な後読みがより直感的です。


もちろん、文字列を文字配列に分割したいだけなら、String#toCharArray()メソッドを使用できます。

于 2013-10-21T19:48:55.757 に答える