# Shortest program to split a string at non-digits without RegExps

EDIT: If you're using Lisp, I have given some guidelines at the bottom in counting bytes.

Objective: Make the shortest function that splits a string at non-digits and returns an array consisting of only digits in each string, without the use of any regular expressions. Leading zeroes are to be included in each string.

## Current Standings (separated in categories):

• C/C++/C#/Java: 68 (C) ....
• GolfScript/APL/J: 13 (APL)
• All others: 17 (Bash, uses tr), 24 (Ruby)

## Rules:

(I apologize for the lengthiness)

1. The format must be as a function with a single string argument. Up to two additional arguments may be added if necessary for the proper return of the array (e.g. sh/csh/DOS Batch needs an extra variable reference to return, etc.).
2. The primary function declaration doesn't count, and nor does importing other standard libraries. #includes, imports, and usings don't count. Everything else does. This does include #defines and helper functions. Sorry for the confusion. Refer to this as a helpful guide as to what does/does not count (written in C-style syntax)
// doesn't count toward total, may be omitted unless
// non-obvious, like half of Java's standard library.
#include <stdio.h>

import some.builtin.Class // doesn't count, see above

#define printf p // counts towards total

/* Any other preprocessor directives, etc. count. */

int i = 0; // counts

someFunction(); // counts

char[][] myMainSplitFunction(char[][] array) { // doesn't count
// Everything in here counts
return returnArray; // Even this counts.
} // doesn't count

/* Everything in here counts, including the declaration */
char[][] someHelperFunction(char[] string) {
// stuff
} // even this counts

3. The output must be a string array or similar (Array lists in Java and similar are acceptable). Examples of accepted output: String[], char[][], Array, List, and Array (object).
4. The array must contain only contain variable-length string primitives or string objects. No empty strings should be present in the return, with the exception below. Note: the strings are to contain a string of consecutive matches, such as the example input and output below.
5. If there are no matches, then the function body should return null, an empty array/list, or an array/list containing an empty string.
6. No external libraries allowed.
7. DOS line endings count as one byte, not two (already covered in meta, but needs emphasized)
8. And the biggest rule here: no regular expressions allowed.

This is a question, so smallest size wins. Good luck!

And here are some example inputs and outputs (with C-style escapes):

Input:  "abc123def456"
Output: ["123", "456"]

Input:  "aitew034snk582:3c"
Output: ["034", "582", "3"]

Input:  "as5493tax54\\430-52@g9.fc"
Output: ["5493", "54", "430", "52", "9"]

Input:  "sasprs]tore\"re\\forz"
Output: null, [], [""], or similar


## Guidelines for Lisp

Here's what does and doesn't count in Lisp dialects:

;;; Option 1

(defun extract-strings (a b) ; Doesn't count
(stuff) ;;; Everything in here counts
) ; Doesn't count

;;; Option 2

(defun extract-strings (string &aux (start 0) (end 0)) ; Doesn't count
(stuff) ;;; Everything in here counts
) ; Doesn't count.

All other lambdas fully count towards the byte count.

• Wasn't this asked before? – Ismael Miguel Feb 23 '14 at 6:02
• Yes, but I re-asked it on Meta and made substantial edits to it before posting it again here. Because of this, it shouldn't be classified as a duplicate (the other related one should be closed if not already). – Isiah Meadows Feb 23 '14 at 6:06
• Shouldn't your "golf" be posted as an answer? – MrWhite Feb 23 '14 at 10:57
• Sorry, but -1 for disallowing GolfScript. All languages should be allowed. – Doorknob Feb 23 '14 at 18:09
• @Doorknob That's true, but I also understand the OP's feelings. People should have a chance to compete even if they don't speak GolfScript, J, or APL (and I'm guilty of perusing the latter in these competitions.) Can you give a look at my proposal in the thread he linked to? – Tobia Feb 23 '14 at 19:45

# Racket 149

Golfed (according to the rules, only the length of the second line counts)

(define (extract-numeric-substrings s)
(let L([x(map string->number(string-split s""))])(set! x(dropf x false?))(if(null? x)x(let-values([(h t)(splitf-at x number?)])(cons(apply ~a h)(L t)
)))))


Ungolfed

(define (extract-numeric-substrings s)
(let L ([x (map string->number (string-split s ""))])
(set! x (dropf x false?))
(if (null? x)
x
(let-values([(h t) (splitf-at x number?)])
(cons (apply ~a h) (L t))))))


Results

(map extract-numeric-substrings '("abc123def456"
"aitew034snk582:3c"
"as5493tax54\\430-52@g9.fc"
"sasprs]tore\"re\\forz"))

'(("123" "456")
("034" "582" "3")
("5493" "54" "430" "52" "9")
())


## Javascript with lambdas, 84

extract=s=>[].reduce.call(s,(r,c)=>r+=(c!=+c?r[r.length-1]==" "?"":" ":c),"").trim().split(" ")


Tested in Firefox 27

## VB.NET, 87

Imports System.Console
Imports System.String
Imports System.Char
Imports System.StringSplitOptions

Module All
Public Function Parse(S As String) As String()
Return Join("",From C In S Select If(IsDigit(C),C," ")).Split({" "},RemoveEmptyEntries)
End Function

Public Sub Main()
For Each S As String In {"abc123def456", "aitew034snk582:3c", "as5493tax54\\430-52@g9.fc", "sasprs]tore\""re\\forz"}
WriteLine(Join(":", Parse(S)))
Next S
End Sub
End Module


According the rules, only content of parse function is calculated:

Return Join("",From C In S Select If(IsDigit(C),C," ")).Split({" "},RemoveEmptyEntries)


I am not counting the imports towards the bytecount, as per the scoring rules. The body of the code is a 1 liner (with semicolons, so there is actually no advantage other than looking more golfed), though I am not sure what to count and what not to count in the function definitions. This was originally longer, but I got inspiration from Coaumdio's and DigitalTrauma's bash solutions.

import Data.Char {-Not counted-}
i x|isDigit x=x;i _=' ';f=words.map i {-Fully Counted-}


i preserves digit characters, and replaces all other characters with space. f just maps i onto a string and then applies words, which splits a string into a list of substrings that were separated by arbitrarily long runs of whitespace. If I am missing any of the rules whereby I can reduce my bytecount by omitting certain characters from the score, I would appreciate comments to that effect.

APL: 22

{(a/1,2</a)⊂⍵/⍨a←⍵∊⎕D}


Explanation:

a←⍵∊⎕D creates boolean of argument (⍵) being a digit (system variable ⎕D contains '0123456789')

⍵/⍨a  takes just the numeric part of the argument

(a/1,2</a)⊂  makes substrings of numbers only, starting at first number found


# Pharo Smalltalk, 60

f:=[:s|(s splitOn:[:e|e isDigit not])reject:[:e|e isEmpty]]


Outputs:

f value:'abc123def456' -> OrderedCollection('123' '456')
f value:'aitew034snk582:3c' -> OrderedCollection('034' '582' '3')
f value:'as5493tax54\430-52@g9.fc' -> OrderedCollection('5493' '54' '430' '52' '9')
f value:'sasprs]tore\"re\forz' -> OrderedCollection()


C# 66

static char[] n(string s){return s.Where(Char.IsDigit).ToArray();}

• This is not a valid solution, I don't think the OP wants you to split on the empty string ;) – VisualMelon Oct 21 '14 at 15:40