# Stripping off extra spaces from a string

You are given a string. Output the string with one space per words.

# Challenge

Input will be a string (not null or empty), surrounded with quotes(") sent via the stdin. Remove leading and trailing spaces from it. Also, if there are more than one space between two words (or symbols or whatever), trim it to just one space. Output the modified string with the quotes.

# Rules

• The string will not be longer than 100 characters and will only contain ASCII characters in range (space) to ~(tilde) (character codes 0x20 to 0x7E, inclusive) except ",i.e, the string will not contain quotes(") and other characters outside the range specified above. See ASCII table for reference.
• You must take input from the stdin( or closest alternative ).
• The output must contain quotes(").
• You can write a full program, or a function which takes input (from stdin), and outputs the final string

# Test Cases

"this  is  a    string   "         --> "this is a string"

"  blah blah    blah "             --> "blah blah blah"

"abcdefg"                          --> "abcdefg"

"           "                      --> ""

"12 34  ~5 6   (7, 8) - 9 -  "     --> "12 34 ~5 6 (7, 8) - 9 -"


# Scoring

This is code golf, so the shortest submission (in bytes) wins.

• You say must take input from stdin, and later you say ...or a function which takes input, and outputs the final string. Does this mean the function must take input from stdin as well? – blutorange May 20 '15 at 15:35
• @blutorange , Yes. Edited to clarify it. – Spikatrix May 20 '15 at 15:36
• " "aa" " --> ""aa"" (are quotes valid inside the input string?) – edc65 May 20 '15 at 15:36
• @edc65 , Good point. The answer to that is no. Edited to clarify it. – Spikatrix May 20 '15 at 15:51
• Please see MickeyT's comment on my answer. Is what he proposes valid? In R, returned results are implicitly printed, but in my answer I've explicitly printed to stdout. – Alex A. May 20 '15 at 19:30

# CJam, 7 bytes

q~S%S*p


Code Explanation

CJam has reserved all capital letters as inbuilt variables. So S has a value of a space here.

q~          e# Read the input (using q) and evaluate (~) to get the string
S%        e# Split on running lengths (%) of space
S*      e# Join (*) the splitted parts by single space
p     e# Print the stringified form (p) of the string.


This removes the trailing and leading spaces as well

Try it online here

# ///: 18 characters

/  / //" /"// "/"/


Sample run:

(Using faubiguy's interpreter from his Perl answer for Interpret /// (pronounced 'slashes').)

bash-4.3$( echo -n '/ / //" /"// "/"/'; echo '" foo * bar "'; ) | slashes.pl "foo * bar"  # Perl, 22 (20 bytes of code, plus 2 command line switches) s/ +/ /g;s/" | "/"/g  Needs to be run with the -np switch so that $_ is automatically filled via stdin and printed to stdout. I'm going to assume this adds 2 to the byte count.

• same solution: sed -E 's/ +/ /g;s/" | "/"/g' – izabera May 20 '15 at 16:01
• The same thing is 12 bytes in Retina. :) – Martin Ender May 20 '15 at 16:24
• -p implies -n, so you only have to take a +1 penalty here (assuming you don't just switch to a different language, like the other commenters suggest). – user62131 Dec 18 '16 at 8:44

# Bash, 36 32 bytes

As a function, a program, or just in a pipe:

xargs|xargs|xargs -i echo '"{}"'


## Explanation

The first xargs strips the quotation marks.

The second xargs trims the left side and replaces multiple adjacent spaces in the middle of the string with one space by taking each "word" and separating each with a space.

The xargs -i echo '"{}"' trims the right side and rewraps the resulting string in double quotes.

• Wow! That is tricky. Unfortunately not handles test case 4, but still impressing. – manatwork May 21 '15 at 7:46
• Yeah, this code meets the fourth test case and is shorter. – Deltik May 21 '15 at 10:27
• Can you do something like this? x=xargs;$x|$x|$x -i echo '"{}"' – Cyoce Sep 1 '17 at 5:09 • @Cyoce: You could indeed do that to save one byte at the cost of losing pipe functionality. Still not as short as this solution and still doesn't satisfy the fourth test case. – Deltik Sep 1 '17 at 7:44 # Ruby, 312925 23 Bytes p$*[0].strip.squeeze' '


Code Explanation:

• p outputs string within double quotes to STDOUT (There's more to it though...)
• $* is an array of STDIN inputs, $*[0] takes the first one
• strip removes starting and ending spaces
• squeeze ' ' replaces >1 space characters with a single space

Test Cases:

• You can replace ARGV with $* saving two bytes. gsub /\s+/, ' ' can be replaced with squeeze ' ' for another 4 bytes – DickieBoy May 22 '15 at 9:57 • @DickieBoy, thank you for $*, I didn't know that. But we can't replace gsub /\s+/, ' ' with squeeze because they are not the same. – Sheharyar May 22 '15 at 10:09
• What do you mean by "are not the same"? The outputs are the same. – DickieBoy May 22 '15 at 10:16
• squeeze ' ' will only squeeze spaces. "yellow moon".squeeze "l" => "yelow moon" – DickieBoy May 22 '15 at 10:24
• Personally I am. And some of other answerers too. But as I see, neither you are alone with your interpretation… A clarification from the question owner would be welcome. By the way, both the space between p and its parameter and squeeze and its parameter are unnecessary. – manatwork May 22 '15 at 10:42

# Pyth, 171511 10 bytes

(thanks to Ypnypn and FryAmTheEggman)

pjd-cQdkNN


Could probably be golfed more.

If the output can use ' instead of " then I only need 8 bytes:

jd-cQdk

• You can use N instead of \" – Ypnypn May 21 '15 at 0:23
• Welcome to Pyth, Tylio. The second program could be shorterned by the use of d. – isaacg May 21 '15 at 7:29
• @isaacg haven't I already used d for everything it can be used for? – Tyilo May 22 '15 at 23:38
• @Tyilo I think you made an edit at about the same time I commented. It's all good now. – isaacg May 22 '15 at 23:48
• You can use p to save a few bytes on string concatenation instead of many +es. pjd-cQdkNN – FryAmTheEggman May 23 '15 at 3:38

fmap(unwords.words)readLn


words splits the string into a list of strings with spaces as delimiters and unwords joins the list of strings with a single spaces in-between. The quotes " are stripped of and put back by Haskell's read and show (implicitly via the REPL) functions on strings.

Outputting by the function itself is three bytes longer, i.e. 28 bytes:

print.unwords.words=<<readLn


Edit: @Mauris pointed to the readLn function, which saved some bytes.

• I'm getting Parse error: naked expression at top level when I tested both the codes here – Spikatrix May 21 '15 at 8:45
• @CoolGuy: rextester.com expects whole programs, not functions, so try main=interact$show.unwords.words.read. There's an online REPL at the frontage of haskell.org (requires cookies enabled) where you can try fmap(unwords.words.read)getLine. – nimi May 21 '15 at 14:19 • fmap(unwords.words)readLn and print.unwords.words=<<readLn are a bit shorter. – Lynn May 23 '15 at 1:38 • @Mauris: thanks for pointing to readLn. – nimi May 23 '15 at 8:31 # R, 45 bytes cat('"',gsub(" +"," ",readline()),'"',sep="")  The readline() function reads from STDIN, automatically stripping any leading and trailing whitespace. Excess space between words is removed using gsub(). Finally, double quotes are prepended and appended and the result is printed to STDOUT. Examples: > cat('"',gsub(" +"," ",readline()),'"',sep="") This is a string "This is a string" > cat('"',gsub(" +"," ",readline()),'"',sep="") 12 34 ~5 6 (7, 8) - 9 - "12 34 ~5 6 (7, 8) - 9 -"  • Not sure if it complies totally with the rules, but the cat may not be totally required, just the gsub. The output from that is [1] "This is a string" – MickyT May 20 '15 at 19:26 • @MickyT: Thanks for the suggestion. My interpretation based on the OP's comment (first on the post) was that it had to be printed to stdout. I'll ask for clarification. – Alex A. May 20 '15 at 19:28 • Ahhh ... didn't see that comment or requirement – MickyT May 20 '15 at 19:30 ## Python2, 37 Reduced by 1 byte thanks to @ygramul. print'"%s"'%' '.join(input().split())  Original version: print'"'+' '.join(input().split())+'"'  Test cases: • I really wanted to use print" ".join(raw_input().split()), but it would have a trailing space inside the last quotation mark if there were spaces after the last word... – mbomb007 May 20 '15 at 19:24 • You can shave off an extra byte using % formatting: print'"%s"'%' '.join(input().split()) – ygramul May 22 '15 at 15:26 # JavaScript (ES6), 49 52 58 Edit 6 bytes shorter, thanks to @Optimizer Edit 2 -3, thanks to @nderscore Input/output via popup. Using template string to cut 1 byte in string concatenation. Run snippet to test in Firefox. alert("${prompt().match(/[^ "]+/g).join(" ")}")

• alert("${eval(prompt()).match(/\S+/g).join(" ")}") - 52 – Optimizer May 20 '15 at 15:50 • @Optimizer thx. Note, that just works after the last clarification about the quotes: eval('" " "') would crash. – edc65 May 20 '15 at 15:55 • When I tested the fourth test case (using chrome), no popup (which shows the result) is seen. Why? – Spikatrix May 21 '15 at 8:42 • @CoolGuy maybe because Chrome does not run ES6? I never test ES6 with Chrome. Anyway I tried it now in my Chrome (42.0.2311.152) and works for me. – edc65 May 21 '15 at 10:49 • -3: alert("${prompt().match(/[^ "]+/g).join(" ")}") – nderscore May 23 '15 at 15:54

# 05AB1E, 9 bytes

#õKðý'".ø


Try it online!

#         | Split on spaces.
õK       | Remove empty Strings.
ðý     | Join with spaces.
'".ø | Surround with quotes.


# Mathematica, 75 bytes

a=" ";b=a...;Print[InputString[]~StringReplace~{b~~"\""~~b->"\"",a..->a}]


# KDB(Q), 28 bytes

" "sv except[;enlist""]" "vs


# Explanation

                       " "vs    / cut string by space
except[;enlist""]         / clear empty strings
" "sv                           / join back with space


# Test

q)" "sv except[;enlist""]" "vs"12 34  ~5 6   (7, 8) - 9 -  "
"12 34 ~5 6 (7, 8) - 9 -"


# Java 8, 43 bytes

s->'"'+s.replaceAll(" +|\""," ").trim()+'"'


Explanation:

Try it here.

s->                           // Method with String as parameter and return-type
'"'                         //  Return a leading quote
+s.replaceAll(" +           //  + Replace all occurrences of multiple spaces
|\"",      //     and all quotes
" ")  //    with a single space
.trim()                   //  And remove all leading and trailing spaces
+'"'                        //  And add the trailing quote
// End of method (implicit / single-line return statement)


# Octave, 44 bytes

@(x)[34 strjoin(regexp(x,'\S+','match')) 34]


Try it online!

# Perl 5, 17 bytes

16 bytes of code + 1 for -p

s/ *("| ) */$1/g  Try it online! # Powershell, 40 bytes ""$(($args-Replace' +'," ").trim())""  Pretty straight forward and not very impressive. Explanation Take input parameter via (predfined) args-variable, replace all multiple spaces with one, trim leading and trailing spaces using trim()-method, add quotes. Powershell will print strings to console as default behavior. # Jq 1.5, 42 bytes split(" ")|map(select(length>0))|join(" ")  Sample Run $ jq -M 'split(" ")|map(select(length>0))|join(" ")' < data
"this is a string"
"blah blah blah"
"abcdefg"
""
"12 34 ~5 6 (7, 8) - 9 -"

$echo -n 'split(" ")|map(select(length>0))|join(" ")' | wc -c 42  Try it online • I caught the output issue earlier (see edit 5) but didn't notice the input issue. The command is fixed now. Thanks! – jq170727 Sep 22 '17 at 14:30 # Tcl, 69 bytes puts [string map {{ "} \" {" } \"} [regsub -all \ + [gets stdin] \ ]]  Try it online! # Tcl, 79 bytes puts \"[string trim [regsub -all \ + [string range [gets stdin] 1 end-1] \ ]]\"  Try it online! • @KevinCruijssen Fixed. unfortunately, at the expense of many bytes. Tks for telling me. – sergiol Sep 22 '17 at 22:25 # Japt-Q, 10 4 bytes ¸f ¸  Try it # Zsh, 15 bytes <<<\"${(Qz)1}\"


Try it online!

Input string contains embedded quotes. Remove the Q for 14 bytes if the input string does not contain embedded quotes, as is done in some of the other answers here.

Parameter expansion flags: Q dequotes, then z splits into words as the shell does. The words are then implicitly joined by spaces.

# Fortran, 147 bytes

Per wikibooks, "It should be remembered that Fortran is designed for scientific computing and is probably not a good choice for writing a new word processor.". Fortran doesn't have a regex concept either. This just makes string challenges more interesting!

In this solution, we trim the string S, then iterate over it. Print each character unless it's a space followed by another space. Try it Online!

character(99)S;read(*,'(A)')S
do i=1,len(S);if(S(i:i+1).ne.'  ')then
endif;enddo;end

• Other ideas failed! print* always prints a leading space and a new line. Writing to a new string (avoiding formatting directives) is annoying because gfortran fills it with garbage! Sigh – roblogic Dec 8 '20 at 12:47

# golfua, 42 bytes

L=I.r():g('%s*\"%s*','"'):g('%s+',' ')w(L)


Simple pattern matching replacement: find any double quotes (\") surrounded by 0 or more spaces (%s*) & return the single quote, then replace all 1 or more spaces (%s+) with a single space.

A Lua equivalent would be

Line = io.read()
NoSpaceQuotes = Line:gsub('%s*\"%s*', '"')
NoExtraSpaces = NoSpaceQuotes:gsub('%s+', ' ')
print(NoExtraSpaces)


# Cobra - 68

As an anonymous function:

do
print'"[(for s in Console.readLine.split where''<s).join(' ')]"'


Objective-C 215

-(NSString*)q:(NSString*)s{NSArray*a=[s componentsSeparatedByString:@" "];NSMutableString*m=[NSMutableString new];for(NSString*w in a){if(w.length){[m appendFormat:@"%@ ",w];}}return[m substringToIndex:m.length-1];}


Uncompressed version:

-(NSString*)q:(NSString*)s{
NSArray *a=[s componentsSeparatedByString:@" "];
NSMutableString *m=[NSMutableString new];
for (NSString *w in a) {
if (w.length) {
[m appendFormat:@"%@ ",w];
}
}
return[m substringToIndex:m.length-1];
}


Bash ,14 bytes

read f;echo \$f       # assume f="this  is  a    string   "

• What about assuming “ foo * bar ” or anything else with a wildcard character? – manatwork May 23 '15 at 14:01

# k4, 23 bytes

" "/:x@&~~#:'x:" "\:0:0


                    0:0  / read from stdin
x:" "\:     / split string on spaces and assign to x
~~#:'            / boolean true where string len>0, bool false otherwise
x@&                 / x at indices where true
" "/:                    / join with spaces


# Wren, 56 bytes

Wait. The replace only does it once? Now I have to use the split-join combo.

Fn.new{|x|x.trim().split(" ").where{|i|i!=""}.join(" ")}


Try it online!

## Explanation

Fn.new{|x|                                             } // New anonymous function with the operand x
x.trim()                                       // Trim out whitespace from both sides of the string
.split(" ")                            // Split the string into space-separated chunks
.where{|i|i!=""}            // Keep all of those that aren't the null string (due to two consecutive spaces)
.join(" ")  // Join the replaced list together


# GolfScript, 8 bytes

' '%' '*


Try it online!

# Explanation

The logic is quite simple:

' '%     # Split on spaces, remove empty results
' '* # Join on spaces


# k4, 21 18 bytes

" "/:!(,"")_=" "\:


Splits the input on spaces, grouping it (resulting in a dictionary of values => indices in which they appear). Removes the empty string "", takes the key of the dictionary, then combines them using " "`.