g | x | w | all
Bytes Lang Time Link
095sed 4.2.2250822T105412ZToby Spe
029Dyalog APL250821T231421ZAaron
nan240622T102352ZRARE Kpo
nanPxem240621T141538Z鳴神裁四点一号
010Nekomata240621T030757Zalephalp
094PowerShell230417T202134ZJames Fl
070C gcc221221T154550Zl4m2
071JavaScript Node.js230414T151643ZFhuvi
055Arturo230412T195107Zchunes
025K ngn/k230412T202454Zcoltim
077Excel VBA221221T224519ZEngineer
086PHP221226T030654ZJames Ri
119Python 3221228T180626ZJoao-3
028Vim221222T155436ZD. Ben K
00705AB1E221221T135731ZThe Thon
156Java 19221227T034037ZJeremy
076Haskell221226T041339ZRoman Cz
068Lua221223T094746Zfartmast
018><>221223T032459ZJo King
088Java221222T195840ZUnmitiga
011Pyth221222T195250ZCursorCo
011Brachylog221222T183006ZDLosc
057Bash extglob221222T165619Zroblogic
086SNOBOL4 CSNOBOL4221221T140116ZGiuseppe
024Zsh extendedglob221222T123913Zroblogic
007Japt221221T123841ZShaggy
054Mathematica 13.1221222T104244ZChris De
612Nibbles221222T074616ZDominic
007Pip221221T123139Zmath sca
057R221221T134406Zpajonk
158Bash221222T040429Zcocomac-
016J221222T031301ZConor O&
057Python221221T222816Zjezza_99
042Factor221222T000744Zchunes
016Perl 5 p221221T235853ZSisyphus
008Husk221221T214459ZDominic
016Ruby221221T194134ZJordan
008Jelly221221T182103ZJonathan
018Raku221221T173233ZSean
063Dart 2.18.4221221T164807ZAlex
027Julia 1.0221221T162529ZMarcMush
020Charcoal221221T155520ZNeil
028><>221221T152144ZEmigna
031JavaScript221221T124041ZShaggy
090Python 3221221T122507ZU13-Forw
055><>221221T125301Zmousetai
008Retina 0.8.2221221T123837ZLuis Men
006Retina 0.8.2221221T123955ZNeil
005QuadR221221T123415ZAdá
007Vyxal s221221T121509Zlyxal

sed 4.2.2, 95 bytes

y/0123456789/a!@#$%^&*(/
:
s/a/<<123456789a01>/
s/(.)<.*\1(a?.).*>/\2/
t
y/!@#$%^&*(/123456789/

How it works

#!/usr/bin/sed -rf

# save existing digits
y/0123456789/a!@#$%^&*(/

# unary to decimal
:
s/a/<<123456789a01>/
s/(.)<.*\1(a?.).*>/\2/
t

# restore digits
y/!@#$%^&*(/123456789/

Try it online!

Dyalog APL, 29 chars

{∊{0∊⍎⍵:⍕≢⍵⋄⍵}¨⍵⊂⍨1,2≠/'0'=⍵}­⁡​‎‎⁡⁠⁢⁢⁤‏⁠‎⁡⁠⁢⁣⁡‏⁠‎⁡⁠⁢⁣⁢‏⁠‎⁡⁠⁢⁣⁣‏⁠‎⁡⁠⁢⁣⁤‏⁠⁠⁠‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁢⁡‏⁠‎⁡⁠⁢⁢⁢‏⁠‎⁡⁠⁢⁢⁣‏⁠⁠⁠‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁡⁣‏⁠‎⁡⁠⁢⁡⁤‏⁠⁠⁠‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏⁠⁠⁠‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠⁠⁠‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌­
                       '0'=⍵   # ‎⁡Find the character 0
                    2≠/        # ‎⁢Compare every two elements for inquality.
                               # ‎⁢  This demarcates where we turn from not-0's to 0's
                  1,           # ‎⁣Shift it over one and start with a 1
               ⍵⊂⍨             # ‎⁤Partition the input with that new mask.
                               # ‎⁤  This is then chunks of 0's and chunks of not-0's
  {          }¨                # ‎⁢⁡For each of those chunks
   0∊⍎⍵                        # ‎⁢⁢if I execute that string and its 0
       :⍕≢⍵                    # ‎⁢⁣  then return a string of its length
           ⋄⍵                  # ‎⁢⁤  else just return it unmodified
 ∊                             # ‎⁣⁡Enlist to join it all as one string again
💎

Created with the help of Luminespire.

awk

(gawk-specific)

gawk 'ORS=length(RT)' RS=0+
1234523623441
123452362344
12
1123456789
1234567891
123456789
11121324151

Pxem, 11 + 52 = 63 bytes

.c.w.n\0.a.s

Filename

\1.rL.w.i.c0.x.t.e.c.-.m.oXX\1.a.c!.x.s\1.+XX\1.a\1.+.a.e

Try it online!

What I have golfed

  1. EOF case out of the loop
  2. How subroutine works

Pxem, 13 + 58 = 71 bytes

.s.c.w.n\0.a.s

Filename

\1.rL.w.i.c\1.+\1.y.e.d.a.c0.x.e.o.s\1.rXX1.a.c1.z.s\1.+XX0.a.a

Try it online!

How I golfed

  1. Push zero by \1.r instead of aa.%.
  2. Put number of zeros at bottom then digit or EOF above.

Pxem, 16 + 61 = 77 bytes

.c.w.naa.%.a.s.s

Filename

aa.%.t.w.i.c\1.y.m.e.d.a.c0.x.m.e.m.-.t.oXX1.a1.z\1.m.+.tXX.a.a

Try it online!

Explained

Filename.

aa.%.t      Store 0 to register because it is initialized with null.
.w          Loop
  .i          Push getchar
  .c\1.y      If EOF
    .m.e.d      Push register, call subroutine, exit
  .a
  .c0.x       If top is greater than 48
    .m.e        Push register, call subroutine
    .m.-.t      Reset register to 0
    .o          putchar pop
  XX1.a         Push 49
  1.z         If pop is NOT 49 
    \1.m.+.t    Increment register
  XX.a
.a          End loop

Content as subroutine. Different space with filename, when return stack is concatenated to caller's stack.

.c.w    If top is not zero
  .n      print popped value as numeric integer
aa.%.a
.s.s    Clean up

Nekomata, 10 bytes

ĉᵐ{ᵉĜ#Mĝ}j

Attempt This Online!

Nekomata is still bad at string challenges.

ĉᵐ{ᵉĜ#Mĝ}j
ĉ               Split into groups of identical characters
 ᵐ{     }       For each group:
   ᵉ  M           Max of the following two:
    Ĝ               Convert string to number
     #              Length
       ĝ          Convert number to string
         j      Join

Using the fact that the length of a positive integer is always less than or equal to the integer itself.

PowerShell, 94 bytes

$r='';$_|sls '0+|[1-9]+'-a|% m*|%{$v=$_.value;('$r+=$v','$r+=$_.length')[$v-match"0+"]|iex};$r

Ungolfed

$args|%{
    
    # empty string to append to
    $r=''
    
    # '0+|[1-9]+' will match full string but split by zeroes and non-zeroes
    $_ | sls '0+|[1-9]+' -a | % m*| %{
        
        # value is the matched string 
        $v=$_.value

        # true = 1; false = 0; shorter than an if statement
        # iex will execute the command in quotes
        ('$r+=$v','$r+=$_.length')[$v-match"0+"] | iex
    }
    
    # prints the results
    $r
}

Try it online!

C (gcc), 70 bytes

n;f(char*a){*a-48?n=!printf(n?"%d":"%c",n?:*a++),*a&&f(a):f(a+!!++n);}

Try it online!

C (gcc), 62 bytes by c--

n;f(int*a){*a-48?n=!printf(n?"%d":a++,n),*a&&f(a):f(a+!!++n);}

Try it online!

JavaScript (Node.js), 71 bytes

Solution without using regexp

s=>s.split(0).map(c=>c?(a?a:"")+(a=1,c):(++a,""),a=0).join``+(--a?a:"")

Try it online!

Arturo, 55 bytes

$=>[chunk&=>[&]|map'g->(`0`=g\0)?->size g->join g|join]

Try it

$=>[                   ; a function, assign input to &
    chunk&=>[&]        ; split input into blocks of equal, contiguous chars
    |                  ; then
    map'g->            ; map over each block and assign current elt to g
        (`0`=g\0)?     ; is the first element of g the character `0`?
        ->size g       ; then map g to the length of g
        ->join g       ; otherwise, map g to its joined string
    |                  ; then
    join               ; join the block of strings and numbers to a string
]                      ; end function

K (ngn/k), 25 bytes

{,/$(.'x)|#'x:(&~=':x)_x}

Try it online!

Excel VBA, 100 77 bytes

Saved 23 bytes thanks to a translation by Taylor Raine

For i=2^15-1To 1Step-1:[B1]=i:[A1]=[Substitute(A1,Rept(0,B1),B1)]:Next:[B1]="

Input is in the cell A1 of the active sheet. Output is in the same cell. The code is run from the immediate window in VBA. The only clever bit is that Excel only allows 32,767 characters in a cell and counting down from there is less bytes than counting down from the length of the input.

PHP, 110 96 94 86 bytes

try{for(;;)if(!~~$c=fgetc(STDIN))$x++;else{echo$x?:"",$c;$x=0;}}finally{echo$x?$x:"";}

Try it online!

Takes input via STDIN, outputs via STDOUT.

Python 3, 120 119 bytes

def f(s):
    c=0;r=''
    for d in s:
        if d=='0':c+=1
        else:r+=f'{c if c!=0 else""}'+d;c=0
    return r+f'{c if c!=0 else""}'

Try it online!

Vim, 28 bytes

:s/0\+/\=len(submatch(0))/g Enter

Try it online!

We cannot use 0* because it matches the empty string between digits.

05AB1E, 7 bytes

0ÃηRāR:

Try it online!

Explanation

0ÃηRāR:   # Implicit input
0Ã        # List intersection with [0]
  ηR      # Reversed prefixes
    āR    # Reversed length range
      :   # Infinite replacement

Previous 13 byte answer

.γ}εD0.åig}}J   # Implicit input
.γ}             # Group by consecutive items
   ε       }    # For each group:
    D           #  Duplicate the group
     0.åi }     #  If 0 is in the group:
         g      #   Push its length
            J   # Join everything into a single string

Java 19, 156 161 162 bytes

interface A{static void main(String[] a){var i=0;var s="";for(var c:a[0].toCharArray())if(c==48)i++;else{s+=i>0?i+""+c:c;i=0;}System.out.print(i>0?s+i:s);}}

Without Java's golfing tax, 113 bytes

var i=0;var s="";for(var c:a[0].toCharArray())if(c==48)i++;else{s+=i>0?i+""+c:c;i=0;}System.out.print(i>0?s+i:s);

Try it online!

Edit: replaced '0' with 48 as suggested in the comments. Thanks!

Edit: String concatentation is shorter than doing var o=System.out;

Haskell, 76 bytes

import Data.List
r s=concat[case t!!0 of '0'->show$length t;_->t|t<-group s]

Try it online!

Lua 68 bytes

s=io.read("*a")for i=#s,1,-1 do s=s:gsub(("0"):rep(i),i)end print(s)

><>, 23 18 bytes

\&l:?n&o]
\i:'0'-?

Try it online!

Java, 88 bytes

s->java.util.regex.Pattern.compile("0+").matcher(s).replaceAll(r->r.group().length()+"")

Try it online!

Pyth, 11 bytes

sm`|vedhdr8

Try it online!

Explanation

sm`|vedhdr8Q    # implicitly add Q to the end
                # implicitly assign Q = eval(input())
         r8Q    # length encode Q
s               # concatenate together
 m              # map over lambda d
  `             # convert to string
   |            # short circuiting or
    ved         # evaluate the second element of d
       hd       # or take the first element of d

Brachylog, 11 bytes

ḅ{ị0&lṫ|}ᵐc

Try it online!

Explanation

I was hoping for some automatic number -> string conversion, but no dice.

ḅ{ị0&lṫ|}ᵐc
ḅ            Break the input string into blocks of identical characters
 {      }ᵐ   Map this predicate to each block:
  ị            Convert to integer
   0           Assert that the result is zero
    &l         If so, get the length of the block
      ṫ        and convert to string
       |       If that failed (because the number wasn't zero), return the block unchanged
          c  Concatenate the results together into a single string

Bash --extglob, 57 bytes

j=$1;for w in ${1//[1-9]/ };{ j=${j/+(0)/${#w}};}
echo $j

Try it Online!

SNOBOL4 (CSNOBOL4), 86 bytes

	I =INPUT
R	I ARB . L SPAN(0) . X REM . I	:F(O)
	O =O L SIZE(X)	:(R)
O	OUTPUT =O I
END

Try it online!

	I =INPUT				;* read input
R	I 					;* Match in I:
	  ARB . L				;*	ARBitrary characters (save as Left part of string) up to
		  SPAN(0) . X			;*	1 or more 0s (save as X)
			      REM . I		;*	REMaining characters (save as I)
					:F(O)	;* On no match, goto O
	O =O L SIZE(X)	:(R)			;* Append L and # of 0s to O and goto R
O	OUTPUT =O I				;* Output O and any remaining characters of I that didn't match
END

Zsh --extendedglob, 24 bytes

<<<${1//(#m)0##/$#MATCH}

Try it Online!

Japt, 7 bytes

r+iT Èl

Try it here

r+iT Èl     :Implicit input of string
r           :Replace
 +i         :  "+" prepended with
   T        :    0, giving the RegEx /0+/g
     È      :  Pass each match through a function
      l     :    Length

Mathematica (13.1) 54 bytes

StringReplace[string,x:"0"..:>ToString@StringLength@x]

Nibbles, 7 6 bytes (12 nibbles)

+.`=$$?`r$@,
  `=$           # chunk the input by
     $          # itself,
 .              # now map over each chunk:
      ?         #   if
       `r$      #   its value as an integer is nonzero
          @     #     return itself
                #   otherwise
           ,    #     return its length
+               # finally, join it all together

enter image description here

Pip, 7 bytes

-1 byte by jezza_99 / DLosc

aR+X0#_

Wow pip is really good at regex

Try It Online!

aR+X0#_
aR+X0     Replace all occurrences of (regexified zero with a +)
     #_   with it's length

R, 64 58 57 bytes

Edit: -1 byte thanks to @Dominic van Essen.

\(x){regmatches(x,t)=Map(attr,t<-gregexpr("0+",x),"m")
x}

Attempt This Online!

R has some weird string manipulation functions...

Bash - 181 158 chars

Edit 1: I used this trick for the for loop, remove whitespace, condence an if statement

n=0;for ((i=0;i<${#1};i++));{ c="${1:$i:1}";if [ $c = '0' ]; then ((n++)); else [ $n -ne 0 ] && { echo -n $n;n=0;};echo -n $c;fi;};[ $n -ne 0 ] && echo -n $n

Explanation

# a counter of how far into a sequence of zeros we are
# this is zero if we're not in a 'zero-sequence'
n=0

# iterate over all the characters
# $1 is the first function argument ($0 would be the script name)
for (( i=0; i<${#1}; i++ )); do
    # get the current char
    c="${1:$i:1}"

    # if it is a zero, then increment the counter
    if [ $c = '0' ]; then
        ((n++));
    # if it is NOT a zero
    else
        # if a zero sequence is over (given that the counter is
        # not equal to zero and the current char isn't zero)
        if [ $n -ne 0 ]; then
            # print the number of zeros in the sequence,
            # and reset the counter to zero
            echo -n $n;
            n=0;
        fi;
    echo -n $c;
    fi
done
# check if there was a zero sequence terminating the string,
# as we wouldn't otherwise check as there wouldn't be a non-zero
# char initiating the check
if [ $n -ne 0 ]; then echo -n $n; fi

I referred to this SO answer for how to iterate over a string in Bash and this AU answer for a short way to increment a variable

J, 16 bytes

'0+'":@#rxapply]

Attempt This Online!

Fairly simple regex solution:

'0+' ":@#rxapply ]
'0+'     rxapply ]    apply to all relevant patterns in the input
        #             length
     ":@              casted to string

J, 47 bytes

' '-.~[:,(1,2~:/\'0'&=)([`(":@#)@.('0'&e.));.1]

Attempt This Online!

Horrendously long non-regex solution. This is the only way I could really think of approaching this, since, afaik, J doesn't have a builtin for grouping according to a boolean matrix or similar.

Python, 62 57 bytes

lambda n:re.sub("0+",lambda s:str(len(s[0])),n)
import re

Attempt This Online!

-5 bytes thanks to @xnor

Regex solution, port of @mathcat's Pip answer

Factor, 42 bytes

[ R/ 0+/ [ length >dec ] re-replace-with ]

Try it online!

Perl 5 -p, 16 bytes

s/0+/length$&/eg

Try it online!

Husk, 8 bytes

ṁ?IosLig

Try it online!

Ruby, 16 bytes

gsub /0+/,&:size

Attempt This Online!

Jelly, 8 bytes

Œgċ”0ȯƊ€

A full program that accepts a string of digit characters and prints the result.

Try it online!

How?

Œgċ”0ȯƊ€ - Main Link: list of characters, S
Œg       - group runs
       € - for each group:
      Ɗ  -   last three links as a monad - f(group):
   ”0    -     literal '0' character
  ċ      -     count occurrences
     ȯ   -     logical OR (group)
         - implicit, smashing print

Raku, 18 bytes

{S:g[0+]=$/.chars}

Try it online!

Dart (2.18.4), 63 bytes

r(s)=>s.replaceAllMapped(RegExp('0+'),(m)=>'${m.end-m.start}');
String replaceZerosWithTheirConsecutiveCounts(String src) {
  return src.replaceAllMapped(
    RegExp('0+'),
    (Match match) => '${match.end - match.start}',
  );
}

Julia 1.0, 27 bytes

!x=replace(x,r"0+"=>length)

Try it online!

Charcoal, 20 bytes

⭆⪪⁻⪫⪪SI⁰_0_×_²_∨№ι0ι

Try it online! Link is to verbose version of code. Explanation:

     S                  Input string
    ⪪                   Split on
       ⁰                Literal integer `0`
      I                 Cast to string
   ⪫                    Join with
        _0_             Literal string `_0_`
  ⁻                     Remove matching substrings
            _           Literal string `_`
           ×            Repeated
             ²          Twice
 ⪪                      Split on
              _         Literal string `_`
⭆                       Map over pieces and join
                №       Count of
                  0     Literal string `0`
                 ι      In current piece
               ∨        Logical Or
                   ι    Current piece

String separators are only needed between consecutive strings so the code has been tweaked to avoid them to reduce the byte count. ⭆S∨Iι_0_ also works instead of ⪫⪪SI⁰_0_ for the same byte count.

><>, 28 bytes

0i:"0"=?v{:?n}ol?!
~1+00.  >

Try it online!

JavaScript, 31 bytes

s=>s.replace(/0+/g,x=>x.length)

Try it online!

Python 3, 91 90 bytes

lambda x:''.join(l>"0"and l or f'{len([*g])}'for l,g in groupby(x))
from itertools import*

Try it online!

-1 byte thanks to The Thonnu

I use the itertools module's groupby function to group consecutively.

><>, 55 bytes

i:'0'= ?v>:0(?;o
='0':i<1<\n$v?
      \+1~  /

Try it

Retina 0.8.2, 8 bytes

(0+)
$.1

Try it online!

How it works

Match runs of zeros (0+), capture each match in a group (( )), replace it with the length of the most recent capture ($.1).

Retina 0.8.2, 6 bytes

0+
$.&

Try it online! Link includes test cases. Explanation: Unary to decimal conversion.

QuadR, 5 bytes

0+
⍵L

Try it online!

0+ Replace any runs of zeros

⍵L with the match Length

Vyxal s, 7 bytes

ĠṠƛ0cßL

Try it Online!

Explained

ĠṠƛ0cßL
Ġ       # Group on consecutive items
 Ṡ      # join each into a single string
  ƛ     # To each group:
   0c   #   if it contains 0:
     ßL #     push the length of the string
        # the s flag joins into a single string

An alternate 8 byter that uses regex match replacement

‛0+$⁽Løṙ

Try it Online!

Explained

‛0+$⁽Løṙ
‛0+       # The string "0+"
   $      # pushed under the input
    ⁽L    # a function object that returns the length of its argument
      øṙ  # replace instances of runs of 0 with their length