-4
\$\begingroup\$

Your task is to create a program which takes a string, and if it contains any numbers, symbols or other non-letter characters, it throws an error. Else, it returns the original string. (The string may include whitespace)

("Letters" are a-z and A-Z)

Examples:

Input: My name is Joe

Output My name is Joe


Input: My username is Joe32

Output: (insert an error)

(FYI this question has nothing to do with Don't Google google. It was identified as a possible copy.)

\$\endgroup\$
13
  • \$\begingroup\$ Can we read the string from stdin? \$\endgroup\$ – sweerpotato Sep 30 '15 at 15:48
  • 2
    \$\begingroup\$ possible duplicate of Don't google "google" \$\endgroup\$ – mbomb007 Sep 30 '15 at 16:05
  • 3
    \$\begingroup\$ When you way "whitespace," do you mean any whitespace character, including tabs and newlines, or only spaces? \$\endgroup\$ – Alex A. Sep 30 '15 at 16:08
  • 2
    \$\begingroup\$ In fact, there are even more whitespace characters in the ASCII range namely vertical tabs, carriage returns and form feeds. \$\endgroup\$ – Martin Ender Sep 30 '15 at 16:39
  • 1
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Except, I can't think of a way to make it throw an error based on the input. :/ \$\endgroup\$ – Martin Ender Sep 30 '15 at 17:05

17 Answers 17

0
\$\begingroup\$

Stax, 8 bytes

êF┼Aµ╧û┤

Run and debug online!

Shortest solution so far but expect to be defeated soon.

Explanation

Uses the unpacked version to explain.

' Vl+-!uy
' Vl+        Alphabet plus space
     -       Remove from input
      !u     If result is not empty raise division by zero error
        y    Else print input
\$\endgroup\$
5
\$\begingroup\$

Julia, 53 bytes

s=readline();ismatch(r"[^a-z\s]"i,s)?error():print(s)

Read a string from STDIN using readline(). If any of its characters are not letters or whitespace (ismatch(r"[^a-z\s]"i, s)) then we error(), otherwise we print(s).

\$\endgroup\$
0
3
\$\begingroup\$

Gema, 14 characters

\W<-L>=@div{;}

Sample run:

bash-4.3$ gema '\W<-L>=@div{;}' <<< 'My name is Joe'
My name is Joe

bash-4.3$ gema '\W<-L>=@div{;}' <<< 'My username is Joe32'
Floating point exception (core dumped)
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 24 bytes

Filter the pipeline input based on whether it matches the regex:

|?{$_-match'^[a-z\s]+$'}

e.g. try it by piping the string in:

PS C:\> "Test Test"|?{$_-match'^[a-z\s]+$'}
Test Test

PS C:\> "Test ! Test"|?{$_-match'^[a-z\s]+$'}

The error message is silence/empty result. It matches case-insensitively by default.

\$\endgroup\$
1
  • \$\begingroup\$ Empty result isn't really an error, though? I came up with param($a)if($a-replace'[a-z\s]',''){1/0;exit}$a for 47 bytes. \$\endgroup\$ – AdmBorkBork Sep 30 '15 at 16:26
2
\$\begingroup\$

C++14, 132 126 121 117 121 bytes

#include<iostream>
main(){std::string s;getline(std::cin,s);for(char c:s)if(!isalpha(c)&!isspace(c))throw;std::cout<<s;}

We read a line from stdin, check if each character is a letter or space - if it's not, we throw an error. Finally outputs the input.

Thanks to Alex A for golfing off two bytes

\$\endgroup\$
2
  • \$\begingroup\$ Isn't std::getline defined in <string> header? Also, I think it is C++11 (I am not saying it is not C++14 though) \$\endgroup\$ – Zereges Sep 30 '15 at 16:14
  • \$\begingroup\$ std::getline isn't defined in <string>. Yes, it probably is - but I'm compiling it in C++14 so I find it safer to write it that way. Thanks anyway :~)! Actually, regular getline is defined in iostream which saves me 5 bytes! \$\endgroup\$ – sweerpotato Sep 30 '15 at 16:20
2
\$\begingroup\$

STATA, 57 bytes

di _r(a)
gl b=1/regexm("$a","^[a-zA-Z ]*$")
di _d($b)"$a"

Uses a regex to match letters and space (STATA's regex doesn't include character classes). Set a variable to 1/match exists. Then it prints a that many times, if match exists=0, it says it's invalid syntax. Otherwise, it prints it 1/1 = 1 time.

\$\endgroup\$
2
\$\begingroup\$

CJam, 18 bytes

q_"  
"'[,_el^|-!/

The multi-line string contains a tabulator, a space and a linefeed.

Try it online in the CJam interpreter.

How it works

q_                    Read all input from STDIN and push a copy.
  "\t \n"             Push that string.
         '[,_el^      Push all letters. See: codegolf.stackexchange.com/a/54348
                |     Concatenate both strings.
                 -    Remove their characters from the copy of the input.
                  !   Logical NOT. Pushes 0 if there are other characters.
                   /  Split. Doesn't affect output if successful. Errors on 0.
\$\endgroup\$
2
\$\begingroup\$

Python 3, 56 characters

import re;print(re.match(r'[a-z\s]+$',input(),2).string)

Usefully, match objects have this attribute string which is

The string passed to match() or search().

while None does not.

In [10]: import re;print(re.match(r'[a-z\s]+$',input(),2).string)
54
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-10-0851dec671d1> in <module>()
----> 1 import re;print(re.match(r'[a-z\s]+$',input(),2).string)

AttributeError: 'NoneType' object has no attribute 'string'

In [11]: import re;print(re.match(r'[a-z\s]+$',input(),2).string)
rffef 
rffef 
\$\endgroup\$
1
\$\begingroup\$

Haskell, 56 bytes

q x|all(`elem`(['a'..'z']++['A'..'Z']++['\t'..'\r']))x=x

Throws the Non-exhaustive patterns in function q error if the string contains forbidden characters.

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 48 46 45 46 31 Bytes

/[^a-z\s]/i.exec(a=prompt())?q:a

Accepts input, searches for invalid characters, if it finds any, returns a truthy value and thus evaluates the undefined character q. Otherwise, returns null and thus returns the string.

Old version, 44 bytes

~(a=prompt()).search(/[^a-z\s]/i)?eval("@"):a

Tries to evaluate the invalid character @ upon finding a numeric.


Edit 1: -2 bytes, thanks to @Alex A.

Edit 2: -1 byte, reworked. BONUS: Accounts for ALL whitespace! ^_^

Edit 3: +1 byte, added underscore testing.

Edit 4: Back to 46, unreworked.

Edit 5: -2 extra bytes to @edc65 (for old version; -1 for new).

\$\endgroup\$
7
  • \$\begingroup\$ Can you use a regex option to make it case insensitive? I don't know the JS regex flavor but you may be able to do /[^a-z ]/gi to save 2 bytes. \$\endgroup\$ – Alex A. Sep 30 '15 at 16:30
  • \$\begingroup\$ Per the OP's comment, looks like we need to account for all whitespace characters, not just spaces. For that you may be able use /[^a-z\s]/gi. \$\endgroup\$ – Alex A. Sep 30 '15 at 16:41
  • \$\begingroup\$ From the OP's second example, it looks like we are supposed to throw the error if numbers are in the string. \$\endgroup\$ – Celeo Sep 30 '15 at 17:04
  • \$\begingroup\$ @AlexA. Yeah; by DeMorgan's laws, the negation of a disjunction (the regular expression) results in a conjuction of the negatives of the expression. Input the expression into RegExr.com to get a visual of the matched expressions. \$\endgroup\$ – Conor O'Brien Sep 30 '15 at 20:43
  • \$\begingroup\$ @edc65 I don't know why your comment was upvoted. You are wrong in your statement. \$\endgroup\$ – Conor O'Brien Sep 30 '15 at 20:49
1
\$\begingroup\$

Python 2, 60 bytes

import re;n=input();print[n][re.sub('[^a-zA-Z\s]+','',n)!=n]

Usage:

$ python -c "import re;n=input();print[n][re.sub('[^a-zA-Z\s]+','',n)!=n]"
"abcdefg"
abcdefg
\$\endgroup\$
1
\$\begingroup\$

Hassium, 166 Bytes

func main(){r="";foreach(c in input()){c=c.toString();if(!("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \t\n\r".contains(c)))throw(c);else r+=c;}println(r);}

Run and see expanded here

\$\endgroup\$
0
1
\$\begingroup\$

PHP, 51 48 bytes

<?=preg_match('/[^a-z\s]/i',$a=$argv[1])?e():$a;

Runs from command line, like:

php test.php "Test me"

Using preg_match is shorter than using ctype_alpha as the latter needs whitespaces to be stripped.


As the error wasn't defined in the challenge, calling an undefined function seems the shortest way to generate an error. So this:

php test.php "Test me, 2"

leads to:

PHP Fatal error: Call to undefined function e()

Edit

Saved 3 bytes by inverting the statement an by using the i-modifier. Thanks to fschmengler.

\$\endgroup\$
2
  • \$\begingroup\$ You can save a few bytes with the case insensitive modifier i instead of a-zA-Z. And even more if you negate the expression: <?=preg_match('/[^a-z\s]/i',$a=$argv[1])?e():$a; (it searches for any character that is not a white space or alphabetic character) I replaced `` with \s because the question said, all whitespaces are allowed. \$\endgroup\$ – Fabian Schmengler Oct 4 '15 at 18:43
  • \$\begingroup\$ @fschmengler Thanks a lot - I've updated the answer. \$\endgroup\$ – insertusernamehere Oct 9 '15 at 7:05
0
\$\begingroup\$

Python 2, 68 71 70 69 bytes

import re;s=raw_input();print s if re.match(r'[a-z\s]+$',s,2)else 0/0

Thanks to Alex A. and Martin Büttner for saving a byte and NightShadeQueen for another byte!

\$\endgroup\$
6
  • \$\begingroup\$ You should be able to shorten your regex by removing the position anchors and the +. You could also take out one of A-Z or a-z if there's an easy way to make it a case-insensitive regex. \$\endgroup\$ – Alex A. Sep 30 '15 at 17:09
  • 1
    \$\begingroup\$ @AlexA. The + has to stay, because the regex ensures that the string consists only of those characters. But I think the anchors might be unnecessary, because IIRC match checks against the entire string anyway (scan looking for substrings instead). \$\endgroup\$ – Martin Ender Sep 30 '15 at 17:13
  • \$\begingroup\$ Thanks both. I was able to remove the beginning anchor as yes, match automatically searches from the start of the string. \$\endgroup\$ – Celeo Sep 30 '15 at 17:18
  • \$\begingroup\$ @AlexA. It looks like I can make the regex case-insensitive with re.match(r'[a-z\s]+$',s,re.I) but it's more bytes than the case-sensitive expression. Thanks though! \$\endgroup\$ – Celeo Sep 30 '15 at 17:22
  • 1
    \$\begingroup\$ re.I is just 2. You could do re.match(r'[a-z\s]+$',s,2) \$\endgroup\$ – NightShadeQueen Oct 1 '15 at 20:58
0
\$\begingroup\$

Java 127 Bytes

class A{public static void main(String[]a){String s=System.console().readLine();System.out.print(s.matches("[A-z ]+")?s:0/0);}}

In Java from the command line you can have input and with the help of regular expression [A-z ]+ which matches alphabets and space in the line, you can have this kind of trick.Moreover, 0/0 will throw ArithmeticException.

\$\endgroup\$
0
\$\begingroup\$

C# - 174 157 148 bytes

using System.Linq;namespace System{class A{static void Main(string[]s){if(!s[0].All(char.IsLetter))throw new Exception();Console.WriteLine(s[0]);}}}

usage:

Console application that takes a parameter in the form of a string and checks via LINQ if all the characters in that string are letters. If so, writes it to console. Otherwise throws exception.

Not particularly short. Will keep tinkering!

Edit: Think I'm pretty much done. Can't get it much shorter don't think.

\$\endgroup\$
0
\$\begingroup\$

Ruby, 26 25 bytes

"undefined method `+@' for nil:NilClass (NoMethodError)":

+(gets=~/^[A-z]*$/);print

Previous 26 bytes, "in `/': divided by 0 (ZeroDivisionError)":

puts gets[/^[A-z]*$/]||1/0
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.