トップページに戻る    次の正規表現パズルへ    前の正規表現パズルへ

6-2 出現回数が2回目以降なら削除その1

正規表現パズル

連続して置換を使って、
行ごとに
行頭から数えた出現回数が、
2回目以降の文字を削除する。

連続置換前


連続置換後


対象データ

AAABBCCDDE
ABCDDEE
AABBCCDD
ABBBCCAAD
XXXXXXXXXX
YYYAAAYYY
ZZZZZ


正規表現

(.)(.*)\1+
を
\1\2
に置換を繰り返す

別解

(.)(.*?)\1+
を
\1\2
に置換を繰り返す


解説

Oracleの正規表現での文字の置換のアレンジ問題です。
Does anyone have some wizzy code or bright ideas?(英語)

キャプチャしながら、マッチを進めて、
後方参照を使ってます。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
.NETの正規表現なら可変長戻り読みを使って
(.)(?<=\1.*\1)
を削除すればよさそうですね。

.NETで可変長戻り読みで
(.)(?<=.*\1.*\1)
を削除する方法

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim work1 As String = "aaaaaa"
    MsgBox(System.Text.RegularExpressions.Regex.Replace(work1, "(.)(?<=\1.*\1)", ""))
    Dim work2 As String = "abababab"
    MsgBox(System.Text.RegularExpressions.Regex.Replace(work2, "(.)(?<=\1.*\1)", ""))
    Dim work3 As String = "abcdeaccc"
    MsgBox(System.Text.RegularExpressions.Regex.Replace(work3, "(.)(?<=\1.*\1)", ""))
    Dim work4 As String = "abbcdeab"
    MsgBox(System.Text.RegularExpressions.Regex.Replace(work4, "(.)(?<=\1.*\1)", ""))
    Dim work5 As String = "abcdefg"
    MsgBox(System.Text.RegularExpressions.Regex.Replace(work5, "(.)(?<=\1.*\1)", ""))
End Sub

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
連続した置換で、最初の文字のみを残す のではなく
連続した置換で、最後の文字のみを残す のであれば

(.)(?=.*\1)
を削除すればいいでしょう。

3-32 置換を使って、同一文字は最後の文字のみを残す