Trim a String without Builtins [closed]

Given text, remove leading and trailing whitespace (spaces, tabs, and newlines).

Alternate title: Implement your own string trimming.

Input

ASCII text (printable + spaces, tabs (\t), and newlines (\n)), in whatever format you would like. Carriage returns (\r) are outside of the scope of the input.

Output

The same text in the same format, but with (only) trailing and leading spaces, tabs, and newlines removed.

Test Cases

This test case ensures that you can handle \s and the like. Please note whitespace in it.

Input

 \s test \t\n



Output

\s test \t\n


For the following test cases (but not the above), \s is space, \t is tab, \n is newline. => splits input and output.

\s\t\n\s => (empty string)

\stest\s => test

\nt\n\st\t => t\n\st

_ => _

\s\s\n\s1\s+\s1\n => 1\s+\s1

||_\s => ||_


No builitins allowed that trim either specific characters or given characters. Builtins that remove arbitrary characters from the beginning/end of a string, or that remove given characters from any position in a string (by default) are allowed.

closed as unclear what you're asking by Sriotchilism O'Zaic, pajonk, Blue, Toto, ArjunSep 22 '17 at 8:04

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

• It's not exactly clear what you mean by no built-ins. Is regex allowed? – DJMcMayhem May 20 '17 at 16:11
• Maybe you mean that a trimming function removes a substring from both sides of a string? – Erik the Outgolfer May 20 '17 at 16:19
• @StephenS Yeah that's what I mean. – Erik the Outgolfer May 20 '17 at 16:21
• How about trimming by an integer amount (rather than "remove occurrence of this character"), dequeuing (removing the first item), popping (removing the last item), rotating, splitting? – Jonathan Allan May 20 '17 at 16:22
• Why would dequeue not be allowed? How is s[1:] trimming? – Dennis May 20 '17 at 16:36

Jelly, 8 bytes

>⁶TṬo\Tị


Try it online!

• Baby, vanilla baby ;) – Okx May 20 '17 at 16:27
• Character comparisons work?! – Jonathan Allan May 20 '17 at 16:28
• @JonathanAllan Why would they not? Integers and character have the same depth. – Dennis May 20 '17 at 16:39
• I just seem to recall them not working. – Jonathan Allan May 20 '17 at 16:41
• @JonathanAllan You probably recall trying to compare strings. That won't work since > vectorizes. – Dennis May 20 '17 at 16:45

^\s+|\s+$ Try it online! Trailing newline is added automatically and is unavoidable. • Retina can do better. I'm really tempted to post it as a separate answer though. – Neil May 20 '17 at 17:07 • @Neil go ahead. – Leaky Nun May 20 '17 at 17:08 • Never mind, found a bug in my answer. – Neil May 20 '17 at 17:09 • might be shorter to use matching with something like: (\S.+?)\s+ – Downgoat May 20 '17 at 17:48 JS (ES6), 27 bytes i=>i.replace(/^\s+|\s+$/g,"")


Carrot, 21 bytes

#^//\S([\s\S]*\S)?/gS


Try it online!

Explanation

Carrot has several global variables, one for each type: string, float and array. The program starts in string-mode, where all the operators will affect the global string variable. And I call these variables the "stack".

#^                     Set the stack-string to the value of all of the input
/                      Get matches of this regex:
/\S([\s\S]*\S)?/g
And set the stack-array to the array containing these matches
There will only ever be one or zero matches
S                      Convert to string-mode by joining the elements of the array


The S operator is supposed to take a string or number as an argument to join the array on, but apparently it is not needed in this case (I don't understand why).

Jelly, 11 8 bytes

-2 bytes thanks to Dennis (use direct character conversion, similar to his answer O>32 -> >⁶
-1 byte thanks to Dennis (removing a redundant quick)

>⁶TṂr$Ṁị  Try it online! Steering clear of anything that could be considered "trimming". How? >⁶TṂr$Ṁị - Main link: list of characters (a.k.a. string)  e.g. "  t xt  "
⁶       - literal space character
>        - greater than (vectorises)                           [0,0,1,0,1,1,0,0]
T      - truthy indexes                                      [    3,  5,6    ]
$- last two links as a monad Ṃ - minimum 3 r - inclusive range [[3],[3,4,5],[3,4,5,6]] Ṁ - maximum [3,4,5,6] ị - index into the input "t xt"  • >⁶TṂr$Ṁị works too. – Dennis May 20 '17 at 16:31

PHP, 40 Bytes

Regex Version

<?=preg_replace("#^\s+|\s+$#","",$argn);


Try it online!

PHP, 77 Bytes

The Regex version was so boring so I would try it without a Regex

<?=substr($a=$argn,strspn($a,$c="\t\n "),-strspn(strrev($a),$c)?:strlen($a));  Try it online! C (gcc) & preprocessor, 152 149 bytes #define f(x)(x==32|x==9|x==10) char*t(char*o){int i=strlen(o);for(;--i>0;){if(!f(o[i]))break;o[i]=0;};while(1){if(f(*o))o=o+1;else break;}return o;}  -3 bytes: Ironically, I forgot to remove my spaces. A function that takes in a char* (pointer to the first character of the string (how C implements strings)), and returns a pointer to the first non-space character in the string, and also replaces all trailing spaces with null bytes, C's string terminator. Ungolfed: #define isspace(x) (x==32|x==9|x==10) // save bytes by not using this whole thing each time // (32 is ' ', 9 is '\t', 10 is '\n') char *trim(char *original) { int i=strlen(original); for(;--i>0;){ // start at the end of the string, work backwards if(!isspace(original[i])) break; // if the character not is a space character, stop working backwards original[i]=0; // else: replace the character with a null byte, C's string terminator } while(1){ if(isspace(original[0]))// shift the pointer until the first char is not a space original = original + 1; else break; } return original; // return the modified pointer } Japt, 9 bytes e"^%s|%s$


Try it online (-Q flag used for visualisation only)

s=>System.Text.RegularExpressions.Replace(s,"^\s+|\s+$","");  If I could use built-ins this is only 12 bytes: s=>s.Trim();  Python 2, 44 bytes lambda s:re.sub(r'^\s*|\s*$','',s)
import re


Try it online!

Non-regex: 62 bytes

Takes input as list of characters. Outputs by reference.

def f(s):exec'while s[%s].isspace():del s[%s]\n'*2%(0,0,-1,-1)