文字列内のすべての数値をインクリメントします


11

10進数を含む文字列がある場合:

teststring134this 123test string54 100

この文字列のすべての数値を1ずつインクリメントして、新しい文字列を提供します

teststring135this 124test string55 101

文字列は次のように提供できます。

  • コマンドライン引数
  • STDIN
  • ハードコーディングされた変数または関数の引数

番号のすべての可能な位置をカバーします:

  • 単語の接頭辞として。123test124test
  • 単語の接尾辞として。test123test124
  • 言葉の中 te123stte124st
  • 単独test 123 testtest 124 test

Pythonのゴルフ以外のソ​​リューションを次に示します。

NUMBERS = '0123456789'

def increment(s):
    out = ''

    number = ''
    for c in s:
        if c in NUMBERS:
            number += c
        else:
            if number != '':
                out += str(int(number) + 1)
                number = ''
            out += c

    if number != '':
        out += str(int(number) + 1)
        number = ''

    return out


print "\"%s\"" % (increment('teststring134this 123test string54 100'))

これはcode-golf質問です。最短のコードが優先されます。


5
楽しい事実:これは3個の純粋な正規表現の置換を行うことができます(なしのコールバック)stackoverflow.com/questions/12941362/...(つまりもののgolfiest方法ではないでしょう)
マーティン・エンダー

4
入力を指定しましたが、出力は指定しませんでした。入力仕様から、STDOUTと戻り値の両方が正常であると想定しています。しかし、結果をハードコードされた変数に格納することもできます(入力を取得できるように)。
マーティンエンダー14

1
持ち運びはどうですか?999はどうなりますか?
ふわふわ14


7
負の数はどうですか?小数点付きの数字はどうですか?(おそらくマイナス記号を除いて)小数点の前に何もない数値はどうでしょうか?
ピーターテイラー14

回答:


23

Perl、14バイト

s/\d+/$&+1/ge

-pスイッチが必要です。これは1バイトとしてカウントしています。

実行例

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

5
ここに私の答えに非常に似ていますhaha codegolf.stackexchange.com/a/37113/29438
hmatt1


11

Vim-13キーストローク

0qqqqq^Al@qq@q

入力が現在の行であることを期待します。

または、8 + ceil(log(n))キーストロークの有限数(たとえば999)の場合:

0qq^Alq999@q

私はこの仕事をすることができないようです....(私はvim 7.0.237を使用しています)
ジェリージェレミア

10

JavaScript(ES6)-28

H=k=>k.replace(/\d+/g,k=>++k)

を使用して実行しH("test 123 234t")ます。


1
あなたはそれを取り出してH=、それを匿名関数にすることができます。
ママファンロール

8

Perl、23

入力文字列が割り当てられていると仮定します $_

s/\d+/@{[$&+1]}/g;print

8

Python 2-59

変数として文字列を提供します n

import re;print re.sub('\d+',lambda x:`int(x.group())+1`,n)

6

C99-86(GCC 4.9.0およびVisual C ++ 2013)

編集:GCC 4.9.0(-std = c99を使用)とVisual C ++ 2013は、インクルードなしで同じコードを(警告を使用して)正常にビルドします。そんなことができるとは知りませんでした!ヒントをありがとう。

編集:文字列を作成して印刷するのではなく、画面にオンザフライで書き込む必要があることさえ私には思いもしませんでした。それは大きな違いになります。ありがとうデニス!

これはハードコードされた文字列を使用していますが、文字列の内容は合計に対してカウントされません(= ""がカウントされます)。

main(i){for(char*q,*s="test123test999test-1test";i=strtol(s,&q,0),*s;q>s?printf("%d",i+1,s=q):putchar(*s++));}

基本的には、文字列を一度に1文字ずつ実行し、それぞれが整数かどうかを確認します。その場合、整数をインクリメントして出力に書き込みます。それ以外の場合は、現在の文字を出力にコピーします。

これは、sをインクリメントするため、ハードコーディングされた文字列をリークします。


1
いくつかのincludes を取り除くことができると確信しており、gccで問題なくコンパイルできます。
マーティンエンダー14

1
これは、例えばを含む文字列で動作し99ますか?
アナトリグ14

@MartinBüttner:はい、しかし、それは有効なCではなく、gccで動作する偶然のことです。
R .. GitHub ICEの

@R .. PPCGでは一般的に許可されています。私は、文句を言うことなく、かなり頻繁にそれを見てきました(そしてその後、それを行いました)。
マーティンエンダー14

はい、それは私の大雑把です。言語は「上C [特定のアーチの/ etcハックは上の仕事に起こる。]」「GCC」またはとして表示されます、それが実際に有効なC.ない場合は、むしろCよりも、または類似:-)
R .. GitHubのSTOP ICEの

5

J(20)

入力が変数に格納されることを期待していますa

'\d+'>:&.".rxapply a

テスト:

   a=:'teststring134this 123test string54 100'
   '\d+'>:&.".rxapply a
teststring135this 124test string55 101

5

(f?)lex(39)

ファイルinc.l

%%
[0-9]+ printf("%d",atoi(yytext)+1);

コンパイル:

$ flex inc.l
$ gcc lex.yy.c -o inc -lfl

実行:

$ echo 'teststring134this 123test string54 100' | ./inc
teststring135this 124test string55 101

$ i='(-: 2 empty bottles of beer :-)'
$ tty=$(tty)
$ for n in {2..5} ; do i=$(./inc<<<$i|tee $tty) ; done
(-: 3 empty bottles of beer :-)
(-: 4 empty bottles of beer :-)
(-: 5 empty bottles of beer :-)
(-: 6 empty bottles of beer :-)

私はオリジナルでこれをテストしませんでしたlex。コメントを歓迎します。


1
%%これはユーザーコードではないため、末尾を削除できます。flex.sourceforge.net
ジョシュ

ねえ...はい!私は試しましたが、末尾の改行なしで失敗しました...最後の改行を追加しようとしませんでした... ;-) ...愚かな間違い!

3

Emacs-20文字

C-M-% [0-9]+ RET \,(1+ \#0) RET !

現在のバッファにテキストを処理する必要があります。ここでは、CM-%を1文字としてカウントしました。これは、3つの修飾子を押したときに1回のキーストロークで入力できるためです。


3

GNU sed、304(-rフラグの1を含む)

私はこの質問を重複の可能性があるとしてクローズ投票しましたが、この答えはそこで働くように簡単に変更することはできないため、これはおそらくそれに反しています。しかし、これまでで一番長い回答です。

sed documentationのこの例に触発されましたが、文字列内の複数の数字を処理するためにいくつかの作業が必要でした:

:d
s/9([^0-9]+|$)/_\1/g
td
s/8(_*)([^0-9]+|$)/9\1\2/g
s/7(_*)([^0-9]+|$)/8\1\2/g
s/6(_*)([^0-9]+|$)/7\1\2/g
s/5(_*)([^0-9]+|$)/6\1\2/g
s/4(_*)([^0-9]+|$)/5\1\2/g
s/3(_*)([^0-9]+|$)/4\1\2/g
s/2(_*)([^0-9]+|$)/3\1\2/g
s/1(_*)([^0-9]+|$)/2\1\2/g
s/0(_*)([^0-9]+|$)/1\1\2/g
s/(^|[^0-9_]+)(_+)/\11\2/g
y/_/0/

出力:

$ for s in "teststring134this 123test string54 100" "123test" "test123" "te123st" "test 123 test" ; do echo "$s" | sed -rf incr.sed ; done
teststring135this 124test string55 101
124test
test124
te124st
test 124 test
$ 

これは一時的に_文字を挿入するため_、入力ストリームにある場合、誤った結果になる可能性があります。これを軽減するため_に、sedスクリプトの一部を印刷できない文字(ASCII 0x07 BELなど)に置き換え、入力ストリームに印刷可能なASCIIのみが含まれていると想定できます。これは、テストするとうまくいくようです。



2

ルア-68文字

d='(%D-)'for k,i,j in s:gmatch(d..'(%d+)'..d)do io.write(k,i+1,j)end

入力がsに保存されることを期待します。


2

CJam、67 58 53 48 31文字

この質問は、CJamにとって最悪の質問のようなものです。正規表現なし、パターンマッチングなし、例外キャッチなし。しかし、ここに行きます(#YOLO)

Sl+_A,sNerN%\[_A,s-Ner~]:)]zs1>

これは、文字列をアルファベットと数字だけのグループに分割します。各桁をインクリメントし、2つの配列をつなぎ合わせて、一度に1つの要素を取得します。


以前のソリューション:

L_l{:Ci57-zA<:RC*+:N\R!N*NNW?i):NL?+RLC?@R*}/NL?

こちらからオンラインでお試しください

使い方:

基本的な考え方は、文字が数字の場合は文字を文字列に個別に保存し、数字以外の文字を取得したら増分値を最終文字列にダンプすることです。

L_                                               "Push two empty strings to stack,"
                                                 "first representing the final string"
                                                 "and second, the current ongoing number";
  l{                                       }/    "Run this block for each character of input string";
    :Ci                                          "Store the character to C and convert to"
                                                 "its ASCII equivalent integer";
       57-zA<:R                                  "Subtract 57 from the integer and compare"
                                                 "its absolute value with 10. Numeric character"
                                                 "would result to true here. Store the result in R";
               C*+:N                             "Take either 0 or 1 characters from C based"
                                                 "on value of R, add it to the second string"
                                                 "from first step. Also store the value in N";
                    \                            "Switch the strings. Now the string containing"
                                                 "the final result string is at top of stack";
                     R!N*                        "If the character was not a digit and N contains a number in it";
                         NNW?i):NL?+             "Convert N to number and increment it."
                                                 "If N is blank, take 0 instead. Put the final"
                                                 "value back in N and add it to the final result string";
                                    RLC?         "If the character was not a digit, push it to stack";
                                        @R*      "Put the ongoing numeric string back to top of stack";
                                             NL? "This is to handle the case when the last number"
                                                 "is not followed by a string, so stack will"
                                                 "have a string at top. Push the value of N to stack in that case";

1

コブラ-88

do(s='')=RegularExpressions.Regex.replace(s,'\d+',do(m as Match)='[int.parse("[m]")+1]')

1

C#の- 178の 169 157文字

これは、999のような数値が000にオーバーフローすることを許可され、-+ ,. Eは数値の一部ではないことを前提としています。

class T{static void Main(){var a="".ToCharArray();for(int b=1,c,i=a.Length;i-->0;b=48>c|c>57?7:b>0?c>56?a[i]='0':++a[i]*0:b)c=a[i];System.Console.Write(a);}}

より読みやすいフォーム:

class T
{
    static void Main()
    {
        var a="7teststring134this 123test string59 100".ToCharArray();

        for (int b=3, c, i=a.Length; i-->0;
            b=48>c|c>57
                ?7
                :b>2
                    ?c>56?a[i]='0':++a[i]*0
                    :b
        ) c=a[i];

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

私はここに新しくて、以前にコードゴルフを試したことはありません、ただ試してみました:)

もっと短くするアイデアがある人はいないだろうか...

C#に参加するには、実際のコードに必要なすべてのフレームワークを省略できると便利です。これは82文字しかなく、強力なシステム関数を呼び出さずに使用できます。


ポインター(182文字)でも同じ:

class T
{
    unsafe static void Main()
    {
        char[] a="7teststring134this 123test string59 100".ToCharArray();

        int b=3;
        fixed (char* s=&a[0])
            for (var p=s+a.Length; p-->s; )
                b=*p<48|*p>57
                    ?7
                    :b>2
                        ?*p>56?*p='0':++*p*0
                        :b;

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

オーバーフローすることなく、これは999ケース(223文字)を正しく処理します。

class T
{
    static void Main()
    {
        var s=new System.Text.StringBuilder("9999teststring134this 123test string99 100");

        for (int b=3, c, i=s.Length; i-->0; )
        {
            c=s[i];
            b=48>c|c>57
                ?b>8?8:7
                :b>2
                    ?c>56?c-(s[i]='0'):++s[i]*0
                    :b;
            if (b>8&i<1|b==8) s.Insert(i+9-b, '1');
        }

        System.Console.Write(s);
        System.Console.ReadKey();
    }
}

別の異なる古いものは、標準入力から読み取り、再帰を使用します。

namespace System {
    using C=Console;
    class T {
        class t {
            byte b=1;
            string s="";
            void R() {
                var c=C.Read();
                if (c>31) {
                    R();
                    if (48>c|c>57) b=1;
                    else if (b==1) c=c==57?48:++c*b--;
                    s=(char)c+s;
                }
            }
            public t() {
                R();
                C.Write(s);
            }
        }
        static void Main() {
            new t();
            C.ReadKey();
        }
    }
}

注:Console.ReadKey();文字列自体はカウントされません。

私はこれをすでに複数回改善しました、コメントを見てください。まだ改善の余地があります。私は言うでしょう:)そして、長さについては申し訳ありませんが、異なるバージョンはそれらを維持するのに十分興味深いと思います...


いいえ、「環境」を取り除くことは許可されていません。の代わりにif(c==57)書くことができた後、2番目のコードを計算します。三項演算子についても同様です。実際には多くのゴルフのトリックがあります。多分あなたは訪問するべきcodegolf.stackexchange.com/questions/2203/tips-for-golfing-in-cc--;c=48;
誇りhaskeller

ありがとう、私はゴルフについて何も知らない:)あなたがここで見るすべては私によって発明された;-) 57-1は48ではない。従って私は理解しない。
maf-soft 14

おっと:-) :-) :-) :-)
誇りに思ってhaskeller 14

私は本当にC#をよく知りませんが、次のようにいくつかの演算子を使用してそれらを結合できると思います... ? ... : c++*b--
誇りに思っているhaskeller 14

:C#のヒントの代わりにあなたのCのヒントを送信するためところで申し訳ありませんcodegolf.stackexchange.com/questions/173/...
誇りhaskellerを

1

Groovy、38バイト

{it.replaceAll(/\d+/,{(it as int)+1})}

Uggghhh ...私は絶対に言葉を憎むreplaceall、彼らは私のためにすべての正規表現golfsを台無しに、。


1
(it as int)+1it.next()
マナトワーク

0

PHP-91バイト

<?$i=fgets(STDIN);for($n=0;$n<strlen($i);$n++)if(is_numeric($i[$n]))$i[$n]=$i[$n]+1;echo$i;

正規表現を使いたくありません。PHPは、文字列オフセットを直接増分することができないため、増分ステップでいくつかのバイトを追加する必要がありました。この1行のスクリプトは、PHPスクリプトの非常に暗い時代を思い出します...


私は今、質問が一連の藻類の結果数を増やすようにあなたに求めることを観察しました。この答えは間違っています。しかし、私は本当に彼が望むものについての詳細を追加する必要があると感じています。
アレクサンドルテレス14


0

sedおよびbash-40(呼び出しおよびパイプを含む)

$ cat << EOF |sed 's/[0-9]\+/$((\0+1))/g;s/^/echo /'|bash
teststring134this 123test string54 100
123test
test123
te123st
test 123 test
EOF

出力:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test

私はこのテスト文字列を試しました:42;rm -rf /それは初めて働きました。
デニス14

2
あなたは変更することができます\0&、(-1文字)$((…))$[…]、(-2文字)s/^/echo /iecho \\ご短縮する(-2文字)現在のコードを。ただし、最初に@Dennisが言及したバグを修正することをお勧めします。(彼は実際にあなたのコードを含む入力に失敗した楽しみのために、問題についてのヒントとして、「これが初めて働いた」書いた;#`…`$(…)あまりにも、おそらく他の特殊文字。)
manatwork

任意のコード実行は機能です:-)
mgjk 14

何らかの種類の入力制限がなく、コードを小さく保つことなく、このルートに進む方法はないかもしれません。解決策の性質は、sedが実行できないため、入力を翻訳し、インタープリターを使用して数学を実行することです。ユーザー入力がインタプリタに到達するとすぐに、エスケープは簡単になります。前のsedの例とは異なり、sedは数学を実行できません。
mgjk 14

やや短い:eval echo `sed 's/[0-9]\+/$[&+1]/g'`-まだ別の同様の質問に私の答えに従って、けれどもコードインジェクションの問題を抱えているcodegolf.stackexchange.com/a/37145/11259
デジタルトラウマ

0

Java 7、119バイト

void c(String s){for(String x:s.split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}

要件が単なる関数ではなくプログラムである場合、149バイトです。

class M{public static void main(String[]a){for(String x:a[0].split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}}

未ゴルフ&テストコード:

ここで試してみてください。

class M{
  static void c(String s){
    for(String x : s.split("(?=[^\\d]+)|(?<=[^\\d]+)")){
      System.out.print(x.matches("\\d+")
                        ? new Long(x) + 1
                        : x);
    }
  }

  public static void main(String[] a){
    c("123test");
    System.out.println();
    c("test123");
    System.out.println();
    c("te123st");
    System.out.println();
    c("test 123 test");
    System.out.println();
    c("7teststring134this 123test string59 100");
  }
}

出力:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101

0

Gema、14文字

<D>=@add{$1;1}

サンプル実行:

bash-4.3$ gema '<D>=@add{$1;1}' <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

0

DASH、16バイト(非競合)

rstr[R"\d+""g"+1

これは、関数/部分アプリケーションを返します。

使用法:

rstr[R"\d+""g"+1]"test 123 234t"

説明

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]

この回答は非競合ですか?
デニス

RIPああ:(私は何とかこれはカタログの質問だと思った。
ママ楽しいロール

0

CJam、18バイト

q_A,s-_:(:`ers~]:)

ここで試してみてください。

説明

q         e# Read input.
_A,s-     e# Duplicate and remove digits.
_         e# Duplicate.
:(:`      e# Decrement and get the string representation of each character.
er        e# Map the characters to the decremented string representation.
s~        e# Flatten to string and evaluate.
]:)       e# Wrap in an array and increment each element.

0

R、83バイト

パーティーに遅れて。入力が変数に格納されていると仮定しますx。おそらくregmatchesこれを解決するために使用する必要はありませんが、外部パッケージなしでベクトル化された置換を見つけることができませんでした。

paste0(el(r(x,m<-gregexpr("\\d+",x),T)),c(as.numeric(el(r(x,m)))+1,""),collapse="")

非ゴルフと説明

r=regmatches                                        # Alias for regmatch
y=r(x<-scan(,""),m<-gregexpr("\\d+",x))             # return match digits
i=r(x,m,T)                                          # return inverted match (non-digits)
paste0(el(i),c(as.numeric(el(y))+1,""),collapse="") # join digits+1 and non-digits, element-wise

出力例

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"

0

C#(Visual C#Interactive Compiler)、コマンドラインオプション/u:System.Text.RegularExpressions.Regex;System.Int32、40バイト

Replace(n,"\\d+",m=>Parse(m.Value)+1+"")

入力がnという名前の変数にあると想定します。

オンラインでお試しください!


2
無効は、変数に入力を期待することはできません
ASCIIのみ

@ ascii-onlyこの質問は明示的にそれを許可しているように見えますが、個人的には、今日の入力標準
ジョーキング

ああ待って:/この質問
ASCIIのみ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.