1

I just finished all the "Easy" CoderByte challenges and am now going back to see if there are more efficient ways to answer the questions. I am trying to come up with a regular expression for "SimpleSymbol".

(Have the function SimpleSymbols(str) take the str parameter being passed and determine if it is an acceptable sequence by either returning the string true or false. The str parameter will be composed of + and = symbols with several letters between them (ie. ++d+===+c++==a) and for the string to be true each letter must be surrounded by a + symbol. So the string to the left would be false. The string will not be empty and will have at least one letter.)

I originally answered the question by traversing through the whole string, when a letter is found, testing on either side to see if a "+" exists. I thought it would be easier if I could just test the string with a regular expression like,

str.match(/\+[a-zA-Z]\+/g) 

This doesn't quite work. I am trying to see if the match will ONLY return true if the condition is met on ALL of the characters in the string. For instance the method will return true on the string, "++d+===+c++==a", due to '+d+' and '+c+'. However, based on the original question it should return false because of the 'a' and no surrounding '+'s.

Any ideas?

1
  • 2
    Could you post your original code since you've done this question? That will help us see what you're talking about more easily. Code > words. Commented Aug 28, 2013 at 22:48

4 Answers 4

1

EDIT: @Marc brought up a very good point. The easiest way to do this is to search for violations using

[^+][a-zA-Z]|[a-zA-Z][^+] 

or something like it. This will find all violations of the rule -- times when a letter appears next to something other than a +. If this matches, then you can return false, knowing that there exist violations. Else, return true.

Original answer:

Here's a regex -- I explain it below. Remember that you have to escape +, because it is a special character!

^([^a-zA-Z+]|(\+[a-zA-Z]\+)|[+])*$ ^ // start of the string [^a-zA-Z+] // any character except a letter or a + (1) | // or (\+[a-zA-Z]\+) // + (letter) + (2) | //or [+] // plus (3) )*$ // repeat that pattern 0 or more times, end 
  • The logic behind this is: skip all characters that aren't relevant in your string. (1)
  • If we have a + (letter) +, that's fine. capture that. (2)
  • if we have a + all by itself, that's fine too. (3)
  • A letter without surrounding + will fail.
Sign up to request clarification or add additional context in comments.

3 Comments

I think that look for the oposite could be easier. Searching by letter+letter or symbol and then use logical negate ;P
Your second regex ^([^a-zA-Z+]|(\+[a-zA-Z]\+)|[+])*$ erroneously matches empty string and strings having no alpha. Also matches stings with illegal chars (only =, + and [A-Za-z] are allowed and string must contain at least one alpha).
@ridgerunner I have given a general regex for this problem that solves this problem in full. Note "the str parameter will be composed of..." And "the string will not be empty and will have at least one letter." If I'm wrong, I'll welcome all correct suggestions. Especially when you have also posted an answer, perhaps a better way to phrase this comment would have been "Note that this regex solves the problem, but not in these special cases that are specified not to appear." (Apologies for typos, on my phone)
1

The problem is that + is a special character in regular expressions. It's a quantifier that means 'one or more of the previous item'. You can represent a literal + character by escaping it, like this:

str.match(/\+[a-zA-Z]\+/g) 

However, this will return true if any set of characters is found in the string matching that pattern. If you want to ensure that there are no other characters in the string which do not match that pattern you could do something like this:

str.match(/^([=+]*\+[a-zA-Z](?=\+))+[=+]*$/) 

This will match, any number of = or + characters, followed by a literal + followed by a Latin letter, followed by a literal +, all of which may be repeated one or more times, followed by any number of = or + characters. The ^ at the beginning and the $ at the end matches the start and end of the input string, respectively. This ensures that no other characters are allowed. The (?=\+) is a look-ahead assertion, meaning that the next character must be a literal +, but is not considered part of the group, this means it can be rematched as the leading + in the next match (e.g. +a+b+).

1 Comment

The regex:^([^a-zA-Z]*\+[a-zA-Z]\+)*[^a-zA-Z]*$ fails to match "+A+A+". Also allows illegal chars (only +, = and alpha allowed). Also matches strings having no alpha (must have at least one.)
0

Interesting problem!

String requirements:

  • String must be composed of only +, = and [A-Za-z] alpha chars.
  • Each and every alpha char must be preceded by a + and followed by a +.
  • There must be at least one alpha char.

Valid strings:

"+A+"
"++A++"
"=+A+="
"+A+A+"
"+A++A+"

Invalid strings:

+=+= # Must have at least one alpha.
+A+&+A+ # Non-valid char.
"+A" # Alpha not followed by +.
"A+" # Alpha not preceded by +.

Solution:

^[+=]*(?:\+[A-Z](?=\+)[+=]*)+$ (with i ignorecase option set)

Here's how I'd do it: (First in a tested python script with fully commented regex)

import re def isValidSpecial(text): if re.search(r""" # Validate special exercise problem string format. ^ # Anchor to start of string. [+=]* # Zero or more non-alphas {normal*). (?: # Begin {(special normal*)+} construct. \+[A-Z] # Alpha but only if preceded by + (?=\+) # and followed by + {special} . [+=]* # More non-alphas {normal*). )+ # At least one alpha required. $ # Anchor to end of string. """, text, re.IGNORECASE | re.VERBOSE): return "true" else: return "false" print(isValidSpecial("+A+A+")) 

Now here is the same solution in JavaScript syntax:

function isValidSpecial(text) { var re = /^[+=]*(?:\+[A-Z](?=\+)[+=]*)+$/i; return (re.test(text)) ? "true" : "false"; } 

4 Comments

Are you sure There must be at least one alpha char is a requirement? It's not stated in the problem statement so presumably ===+++ is a valid string.
@slebetman - See the last sentence: The string will not be empty and will have at least one letter
Yes, there must be one alpha. +(alpha)+ is the correct sequence. Thanks for all your help.
I'm pretty sure that your first and third requirements are given in the problem statement as input guarantees rather than conditions. As in: all strings we test will be of this form.
0
/^[=+]*\+[a-z](?=\+)(?:\+[a-z](?=\+)|[+=]+)*$/i.test(str) 

pattern details:

 ^ # anchor, start of the string [=+]* # 0 or more = and + \+ [a-z] (?=\+) # imposed surrounded letter (at least one letter condition) (?: # non capturing group with: \+[a-z](?=\+) # surrounded letter | # OR [=+]+ # + or = characters (one or more) )* # repeat the group 0 or more times $ # anchor, end of the string 

To allow consecutive letters like +a+a+a+a+a+, I use a lookahead assertion to check there is a + symbol after the letter without match it. (Thanks to ridgrunner for his comment)

Example:

var str= Array('+==+u+==+a', '++=++a+', '+=+=', '+a+-', '+a+a+'); for (var i=0; i<5; i++) { console.log(/^[=+]*\+[a-z](?=\+)(?:\+[a-z](?=\+)|[+=]+)*$/i.test(str[i])); } 

2 Comments

Fails to match "+A+A+".
Yup that fixes it. (But see my answer for a cleaner approach.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.