質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • 正規表現

    814questions

    正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

  • Perl

    461questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • 置換

    40questions

    置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

なぜ、$を付けるとカンマだらけにならなくなるのか

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 2,307

aaaaaaaa

score 469

9ケタの数字、例えば「555555555」のような数字に3の倍数個ずつカンマを振り分ける際は、下記のように記述します。

s/(?<=\d)(?=(?:\d\d\d)+$)/,/


しかし、上記の数字がそれこそ「9ケタの数字、例えば「555555555」のような数字に3の倍数個ずつカンマを振り分ける際は、下記のように記述します。」という文章のように文字列の中に埋もれていた場合、
マッチしなくなります。マッチさせるために、末尾に三桁の数字、を意味する「$」を削除してしまうと、「えば「5,5,5,5,5,5,555」のような…」とカンマだらけになります。$が無くなったことで、残った条件が「左に数字、右に3の倍数個の数字」となるので、カンマだらけになる理由は、解かります。
疑問点は、なぜ$を消しただけでこのようにカンマだらけになってしまうのかです。
逆にいうと、なぜ末尾に三桁という条件を付けるとカンマだらけにならなくなるのかが解かりません。

ちなみに文字列中の数字にカンマをいれるときの正規表現は、「

s/(?<=d)(?=(?:\d\d\d)+)\b/,/

`
だと認識しております。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+5

s/(?<=\d)(?=(?:\d\d\d)+$)/,/


これの検索条件を日本語で表すと
「直前に数値が存在し、直後に1つ以上の”3桁の数値の塊り”が行末まで続くという条件を満たす”位置”」となります。(※文字は一つも指定されてないので位置ですね。)
例えば「555555555」の場合、「5」と「55555555」の間を見ると、”3桁の数値の塊り”が2つ続いたあと、末尾までに「55」が残りますので条件を満たしません。

行末記号を消した場合

s/(?<=\d)(?=(?:\d\d\d)+)/,/


「直前に数値が存在し、直後に1つ以上の”3桁の数値の塊り”が続くという条件を満たす”位置”」です。
「ここから555555555ここまで」の文字列を見ると、「ら」と「5」の間つまり数値の先頭には、その前に数値が無いので条件を満たしませんが、それ以降は条件を満たします。
例えば[5]と「55555555」の間を見ると、直前に数値があり、その後方には3桁以上の数値の塊りが1つ以上存在しています。
そして最後の3桁に入ると、後ろに3桁以上の数値が存在しなくなるので、条件を満たさなくなります。
従って「ここから5,5,5,5,5,5,555ここまで」こうなるでしょう。

文字列中の数字にカンマをいれるときの正規表現

s/(?<=\d)(?=(?:\d\d\d)+(\D|$))/,/g


※コメントで指摘いただき修正しました(5/24)
恐らくこんな感じ?
例によって日本語訳すると
「直前に数値が存在し、直後に1つ以上の”3桁の数値の塊り”が数値以外に行き当たるまで続くという条件を満たす”位置”」

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/24 19:25

    gのフラグ忘れていませんか? ちなみに私なら`\D`の代わりに`(\D|$)`がいいかな。数字が文末にあっても当てはまるからです。

    キャンセル

  • 2016/05/24 23:00

    仰るとおり両方必要ですね。
    ご指摘ありがとうございます。

    キャンセル

+1

Perlは文字列の可能な限り最も早い位置でマッチングを 行おうとします。 
引用元

引用元にある通り、正規表現の基本挙動に従ってるだけです。

(/g の欠落は補完させて頂くとして)

s/(?<=\d)(?=(?:\d\d\d)+$)/,/g


の、(?=(?:\d\d\d)+$) が、3の倍数個の数字の連続が、(その時点での)最長になる位置を示すので、希望通りの挙動を示すのに対し、

後者は実質、

s/(?<=\d)(?=(?:\d\d\d))/,/g

と同じで、$ が無くなる事によって、最低3個の数字が連続する、最も最初の位置を示す事になりますので、一文字づつの置換となります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

マッチしていたら5の個数は減るはずですよね。結果を見ると文字間(0文字)にマッチしているようです。
先読み(<?=)・後読み(?=)の間の「本体にあたる部分」がないので、先読みの(<?=)を外せば意味を成すようになるのではないでしょうか。

,を複数入れるのでgオプションは必須です。
3桁ごとに一回の置き換えなので、(¥d¥d¥d)+とはできません。9桁でも,ひとつだけの出力になってしまいます。
元の文字は1文字も失わないようにするので、(?:)ではなく()を使って、後方参照できるようにします。

s/(¥d¥d¥d)(?=¥d)/$1,/g

でもこれだと「左から3桁ずつ」なので、よくないですね。
終端から先頭方向へマッチする表現が無いので、文字を逆順にするか、繰り返し処理する必要があると思います。

# 逆順にして置き換え処理
$a = '「555555555」';
$a = reverse $a;
$a =~ s/(\d\d\d)(?=\d)/$1,/g;
$a = reverse $a;
print $a;
# 繰り返し
$a = '「555555555」';
while($a =~ s/(?<=\d)(\d\d\d)(?=\D)/,$1/){};
print $a;

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

同じタグがついた質問を見る

  • 正規表現

    814questions

    正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

  • Perl

    461questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • 置換

    40questions

    置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。