# Increment every number in a string

Given a string containing decimal numbers:

teststring134this 123test string54 100

increment every number in this string by one to give the new string

teststring135this 124test string55 101.

The string can be provided as:

• a command line argument
• STDIN
• a hard-coded variable or function argument

Cover all possible positions for a number:

• as a prefix for a word; 123test124test
• as a suffix for a word; test123test124
• inside a word; te123stte124st
• alone test 123 testtest 124 test

Here's a non-golfed solution in 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'))


This is a code-golf question, shortest code wins.

• Fun fact: this can be done with 3 pure regex substitutions (no callbacks) stackoverflow.com/questions/12941362/… (that wouldn't be the golfiest way though) Commented Sep 21, 2014 at 11:19
• You specified input but not output. From your input spec I assume both STDOUT and and return value are fine. But can we also store the result in a hardcoded variable (just as we can take input from it)? Commented Sep 21, 2014 at 11:23
• What about carrying? What happens to 999? Commented Sep 21, 2014 at 17:13
• possible duplicate of Multiply all numbers in a string Commented Sep 21, 2014 at 18:52
• What about negative numbers? What about numbers with a decimal point? What about numbers with a decimal point and nothing before it (except perhaps for a minus sign)? Commented Sep 21, 2014 at 20:45

# Perl, 14 bytes

s/\d+/$&+1/ge  Requires the -p switch, which I have counted as one byte. ### Example run $ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100' teststring135this 124test string55 101  ## Ruby, 30 24 bytes $><<s.gsub(/\d+/,&:next)


Expects the input to be stored in s.

s/\d+/@{[$&+1]}/g;print  # Python 2 - 59 Supply the string as the variable n import re;print re.sub('\d+',lambda x:int(x.group())+1,n)  # C99 - 86 (GCC 4.9.0 and Visual C++ 2013) Edit: Both GCC 4.9.0 (with -std=c99) and Visual C++ 2013 successfully build (with warnings) the same code without the includes. I didn't know you could do that! Thanks for the hint. Edit: It didn't even occur to me that I should write it to the screen on the fly instead of creating the string and then printing it. That makes a huge difference. Thanks Dennis! This is using a hard coded string but the contents of the string are not counted towards the total (the ="" is counted). main(i){for(char*q,*s="test123test999test-1test";i=strtol(s,&q,0),*s;q>s?printf("%d",i+1,s=q):putchar(*s++));}  Basically it runs through the string one character at a time checking each to see if it is an integer. If it is then it increments the integer and writes it to the output otherwise it copies the current character to the output. This leaks the hardcoded string because it increments s. • I'm sure you can get rid of some of the includes and it will still compile fine with gcc. Commented Sep 21, 2014 at 11:58 • Will this work with a string containing e.g. 99? Commented Sep 21, 2014 at 16:32 • @MartinBüttner: Yes but then it wouldn't be valid C, just something that happens to work on gcc. Commented Sep 21, 2014 at 18:46 • @R.. That's generally allowed on PPCG though. I've seen (and subsequently done) it quite often without anyone complaining. Commented Sep 21, 2014 at 19:58 • Yes, and it's a general peeve of mine. The language should be listed as "GCC" or "C on [particular arch/etc. the hacks happen to work on]" or similar, rather than C, if it's not actually valid C. :-) Commented Sep 21, 2014 at 20:01 ## J (20) Expects the input to be stored in the variable a. '\d+'>:&.".rxapply a  Test:  a=:'teststring134this 123test string54 100' '\d+'>:&.".rxapply a teststring135this 124test string55 101  # (f?)lex (39) File inc.l: %% [0-9]+ printf("%d",atoi(yytext)+1);  Compile: $ flex inc.l
$gcc lex.yy.c -o inc -lfl  Run: $ 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 :-)  I did not test this with the original lex. Comments are welcome. • You can drop the trailing %% since this is no user code: flex.sourceforge.net/manual/… – Josh Commented Sep 24, 2014 at 19:41 • Hey... yes! I tried but without trailing newline and that failed... then I didn't try to add the final newline... ;-) ...stupid mistake! – user19214 Commented Sep 24, 2014 at 20:54 # Emacs - 20 characters C-M-% [0-9]+ RET \,(1+ \#0) RET !  Requires text to be processed to be present in the current buffer. I counted C-M-% as one character here since it can be entered with one keystroke when holding down three modifiers. # GNU sed, 304 (including 1 for -r flag) I close-voted this question as a possible duplicate, but this is perhaps contrary to that because this answer can't be trivially changed to work there. By far the longest answer though. Inspired by this example from the sed documentation, though it needed some work to handle multiple numbers in a string: :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/  ### Output: $ 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$


Note this temporarily inserts _ characters, so could lead to incorrect results if there are _ in the input stream. As a mitigation to this, we can replace the _ in the sed script with some non-printable character (e.g. ASCII 0x07 BEL), and assume the input stream contains only printable ASCII. This seems to work fine when I test it.

# Racket 74

(define(f x)(regexp-replace* #px"\\d+"x(λ(m)(~a(+ 1(string->number m))))))


## Lua - 68 characters

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


Expects the input to be stored in s.

## CJam, 67 58 5348 31 characters

This question is like the worst question for CJam. No regex, no pattern matching, no exception catching. But here we go (#YOLO)

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


This one splits the string in group of just alphabets and just digits. The increments each digit and stitches back the two array taking one element of each at a time.

Previous solution:

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


Try it online here

How it works:

Basic idea is to keep storing the character separately in a string if it is a digit and dump the incremented value to the final string once we get a non digit character.

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";
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";


# Cobra - 88

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


# C# - 178169 157 characters

This assumes that numbers like 999 are allowed to overflow to 000 and that -+,.E are not part of a number.

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);
}
}


I'm new here, never tried code golf before, just gave it a try :)

I wonder if anyone has ideas to get it even shorter...

To participate with C# it would be nice if we could omit all the necessary framework around the actual code - then this would only have 82 chars, and that without calling any powerful system functions.

The same with pointers (182 chars):

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);
}
}


Now without overflowing, this correctly handles the 999 case (223 chars):

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);
}
}


Another different older one, it reads from standard input and uses recursion:

namespace System {
using C=Console;
class T {
class t {
byte b=1;
string s="";
void R() {
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();
}
}
}


Note: Console.ReadKey(); and the string itself should not be counted.

I improved this already multiple times, see comments. There is still room for more improvements, I would say :) And sorry for the length, but I think the different versions are interesting enough to keep them...

• no, getting rid of the "environment" isn't allowed. i reckon in your second code after if(c==57) you could write c--; instead of c=48;, what about the ternary operator too. there is infact a lot of golfing tricks. maybe you should visit codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c Commented Sep 23, 2014 at 17:18
• Thanks, I know nothing about golf :) everything you see here was invented by me ;-) 57-1 isn't 48. So I don't understand. Commented Sep 23, 2014 at 17:22
• Oops :-) :-) :-) :-) Commented Sep 23, 2014 at 17:24
• I don't really know C# well, but I guess you can use some operator to stick them together like ... ? ... : c++*b-- Commented Sep 23, 2014 at 17:51
• btw sorry for sending you the C tips instead of the C# tips: codegolf.stackexchange.com/questions/173/… Commented Sep 23, 2014 at 17:53

# Groovy, 38 bytes

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


Uggghhh... I absolutely hate the words replace and all, they ruin all regex golfs for me.

• (it as int)+1it.next() Commented Nov 11, 2016 at 12:28

# AWK, 40 bytes

BEGIN{RS="[0-9]+";ORS=e}$0=$0(RT?RT+1:e)


Try it online!

Parses each substring of numbers as a record separator (default is a newline, "\n"). Adds one to the record text (RT), that is the number that previously matched to the regex. Except for the last RT, which is null. That's what the last condition is about. Otherwise, there would be a 1 appended to the end of the output.

# Perl 6, 13 bytes

{S:g{\d+}+=1}


Try it online!

Very simple regex substitution that just increments each instance of a series of digits

# Brachylog, 17 bytes

~c{ịᵐc+₁ṫ|ịˢĖ&}ᵐc


Try it online!

### Explanation

~c{ịᵐc+₁ṫ|ịˢĖ&}ᵐc
~c                 Partition the input string such that
{           }ᵐ   this predicate can be applied to each substring:
Either:
ịᵐ                Convert each character to a number (i.e. they are all digits)
c               Concatenate the digits into a single number
ṫ            Convert back to a string
|          Or:
ịˢ         Find all characters that can be converted to a number
Ė        Assert that that list is empty (i.e. none of them are digits)
&       Return the substring unchanged
c  Concatenate the results back into a single string


# Vyxals, 8 bytes

⁽±Ḋƛ±[⌊›


Try it Online!

Who needs regex amiright?

## Explained

⁽±Ḋƛ±[⌊›
⁽±Ḋ      # Group the input by whether each item is numeric
ƛ     # To each group:
±[   #   If it's numeric:
⌊› #     Cast to int and increment
# -s flag sums into a single string.

• How does it work though? Commented Sep 3, 2022 at 4:27

## PHP - 91 Bytes

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


I don't wanted to use regular expressions. PHP isn't capable to directly increment a string offset, so, I needed to add some bytes on the increment step. This one line script remembers me a very dark age of the PHP scripting...

• I have observed just now that the question asks you to increment the result number of a sequence of algarisms. This answer is incorrect. But I really feel that the op should add more details about what he wants. Commented Sep 23, 2014 at 13:15

# K, 56

{" "/:{,/$($a)^1+"I"$a:_[;x]@&~~':x in .Q.n}'" "\:x}  sed and bash - 40 (including invocation and pipes) $ cat << EOF |sed 's/[0-9]\+/$((\0+1))/g;s/^/echo /'|bash teststring134this 123test string54 100 123test test123 te123st test 123 test EOF  Outputs: teststring135this 124test string55 101 124test test124 te124st test 124 test  • I tried this test string: 42;rm -rf / It worked the first time. Commented Sep 26, 2014 at 13:22 • You can change \0 to & (-1 char), $((…)) to $[…] (-2 chars), s/^/echo / to iecho \\ (-2 chars) to shorten your current code. However better fix the bug mentioned by @Dennis first. (He wrote “It worked the first time” for fun and as hint about the issue. Actually your code fails on input containing ;, #, …, $(…) and maybe other special characters too.) Commented Sep 26, 2014 at 14:34
• Arbitrary code execution is a feature :-)
– mgjk
Commented Sep 26, 2014 at 14:37
• There may be no way to go this route without some kind of input restrictions and keeping the code tiny. The nature of the solution is to translate the input and use an interpreter to do the math since sed can't do it. As soon as user input hits an interpreter, the escaping is nuts. Short of the previous sed example, sed can't do math.
– mgjk
Commented Sep 26, 2014 at 15:43
• Somewhat shorter: eval echo sed 's/[0-9]\+/$[&+1]/g' - still has the code injection problem though, as per my answer to another similar question codegolf.stackexchange.com/a/37145/11259 Commented Sep 26, 2014 at 18:55 # Java 7, 119 bytes void c(String s){for(String x:s.split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}  If the requirement is a program instead of just a function, then it's 149 bytes: 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);}}  Ungolfed & test code: Try it here. 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"); } }  Output: 124test test124 te124st test 124 test 8teststring135this 124test string60 101  # Gema, 14 characters <D>=@add{$1;1}


Sample run:

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


# CJam, 18 bytes

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


Try it here.

### Explanation

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.


## R, 83 bytes

Late to the party. Assumes input is stored in variable x. It's probably not needed to use regmatches to solve this but I couldn't figure out vectorized replacements without any external packages.

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


Ungolfed and explained

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


Example output

input:
"teststring135this 124test string55 101"

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


# C# (Visual C# Interactive Compiler) with command-line option /u:System.Text.RegularExpressions.Regex;System.Int32, 40 bytes

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


Expects input to be in a variable named n.

Try it online!

• Invalid, cannot expect input in a variable Commented Jan 31, 2019 at 9:10
• @ascii-only This question seems to explicitly allow it' though personally, I would try to stick to today's input standards
– Jo King
Commented Jan 31, 2019 at 11:45
• Oh wait :/ ew this question Commented Jan 31, 2019 at 23:57

# Stax, 9 bytes

ü╜≥NÇNX╪ÿ


Run and debug it

regex