Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match the same start and end character of a string with Regex

I'm trying to match the start and end character of a string to be the same vowel. My regex is working in most scenarios, but failing in others:

var re = /([aeiou]).*\1/; re.test(str); 

Sample input:

  • abcde, output - false (Valid)
  • abcda, output - true (Valid)
  • aabcdaa, output - true (Valid)
  • aeqwae, output - true (Not valid)
  • ouqweru, output - true (Not valid)
like image 610
Nesh Avatar asked Sep 24 '17 07:09

Nesh


People also ask

What matches the start and end of the string?

They are called “anchors”. The caret ^ matches at the beginning of the text, and the dollar $ – at the end. The pattern ^Mary means: “string start and then Mary”.

How do you specify the end of a string in regex?

End of String or Line: $ The $ anchor specifies that the preceding pattern must occur at the end of the input string, or before \n at the end of the input string. If you use $ with the RegexOptions. Multiline option, the match can also occur at the end of a line.

How do I match a character in regex?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).

How do you start and end a regular expression?

To match the start or the end of a line, we use the following anchors: Caret (^) matches the position before the first character in the string. Dollar ($) matches the position right after the last character in the string.


2 Answers

You need to add anchors to your string.

When you have, for example:

aeqwae 

You say the output is true, but it's not valid because a is not the same as e. Well, regex simply matches the previous character (before e), which is a. Thus, the match is valid. So, you get this:

[aeqwa]e 

The string enclosed in the brackets is the actual match and why it returns true.

If you change your regex to this:

/^([aeiou]).*\1$/ 

By adding ^, you tell it that the start of the match must be the start of the string and by adding $ you tell it that the end of the match must be the end of the string. This way, if there's a match, the whole string must be matched, meaning that aeqwae will no longer get matched.

A great tool for testing regex is Regex101. Give it a try!

Note: Depending on your input, you might need to set the global (g) or multi-line (m) flag. The global flag prevents regex from returning after the first match. The multi-line flag makes ^ and $ match the start and end of the line (not the string). I used both of them when testing with your input.

like image 180
dodov Avatar answered Sep 22 '22 07:09

dodov


Just a different version of @Hristiyan Dodov answer that I have written for fun.

regex = /^(a|e|i|o|u).*\1$/    const strings = ['abcde', 'abcda', 'aabcdaa', 'aeqwae', 'ouqweru']    strings.forEach((e)=>{    const result = regex.test(e)    console.log(e, result)  })
like image 40
Pablo Avatar answered Sep 18 '22 07:09

Pablo