Detect pattern of hyphens in the given string of three words - javascript

I want to search if a string contains the following pattern which simply consists of two - signs (hyphens) separated with single words, not phrases or sentences:
word - word - word
Other conditions simply could be ignored. Spaces between don't affect the pattern so the above pattern and this one are the same:
word - word-word
If there is such a pattern I want to return true and else I want a false obviously!
So far I split the string by hyphens and check if there are two of them only and there are only 3 single words not more and not less, but I think there may be a more efficient way...

You can use the regular expression /^[a-z]+\s*-\s*[a-z]+\s*-\s*[a-z]+$/i.
Explanation:
/ - regular expression literal
^ - start of string
[a-z]+ - one or more lowercase alphabetic characters
\s* - zero or more whitespace characters
- - matches a literal hyphen character
$ - end of string
i - ignore case
function check(str){
return /^[a-z]+\s*-\s*[a-z]+\s*-\s*[a-z]+$/i.test(str);
}
console.log(check('word - word - word'));
console.log(check('Word - word-word'));
console.log(check('invalid - string'));

You can use RegEx to resolve easily your question.
function myTest(str) {
return /^\w+( ?- ?\w+){2}$/.test(str)
}
Edit : my answer is basically a TL;DR to this answer, which explains more deeply how it works. Note that you can change the \w+ with others expressions depending on how you define a word

Regular Expression can be used for this.
The following regular expression will work for your use case.
^[a-z]+\s*-\s*[a-z]+\s*-\s*[a-z]+$
Example:
/^[a-z]+\s*-\s*[a-z]+\s*-\s*[a-z]+$/i.test("word - word - word");

You should be able to check for your pattern using a regular expression and the String.prototype.match() method:
'word-word-word'.match(/^(?:\w+\s?-\s?){2}\w+$/) // --> will return an array containing the match
'word word word'.match(/^(?:\w+\s?-\s?){2}\w+$/) // --> will return `null`
Now, that assumes that the examples above should not contain additional words around the pattern to be checked. If you want to allow for additional characters around the pattern you should be able to just omit the ^ and $ tokens in the pattern:
'something word-word-word somgthing'.match(/(?:\w+\s?-\s?){2}\w+/) // --> will return an array containing the match
'something word word word something'.match(/(?:\w+\s?-\s?){2}\w+/) // --> will still return `null`
Hope that helps!

Related

Regular Expression for Blocking a character in begining

I am facing an issue with a regular expression while trying to block any string which has minus(-) in the beginning of some white listed characters.
^(?!-.*$).([a-zA-Z0-9-:#\\,()\\/\\.]+)$
It is blocking minus(-) at place and allowing it any where in the character sequence but this regex is not working if the passed string is single character.
For e.g A or 9 etc.
Please help me out with this or give me a good regex to do the task.
Your pattern requires at least 2 chars in the input string because there is a dot after the first lookahead and then a character class follows that has + after it (that is, at least 1 occurrence must be present in the string).
So, you need to remove the dot. Also, you do not need to escape any special char inside a character class. Besides, to avoid matching strings atarting with - a mere (?!-) will suffice, no need adding .*$ there. You may use
^(?!-)[a-zA-Z0-9:#,()/.-]+$
See the regex demo. Remember to escape / if used in a regex literal notation in JavaScript, there is no need to escape it in a constructor notation or in a Java regex pattern.
Details
^ - start of a string
(?!-) - cannot start with -
[a-zA-Z0-9:#,()/.-]+ - 1 or more ASCII letters, digits and special chars defined in the character class (:, #, ,, (, ), /, ., -)
$ - end of string.
If i understand correctly, and you don't want a minus at the beginning, does ^[^-].* work as a regex for you? Java's "matches" would return false if it starts with minus
There is a method in a String class that provides you exactly what you are asking for - it's a startsWith() method - you could use this method in your code like this (you can translate it as "If the given String doesn't start with -, doSomething, in other case do the else part, that can contain some code or might be empty if you want nothing to be done if the given String starts with - ") :
if(!(yourString.startsWith("-"))) {
doSomething()
} else {
doNothingOrProvideAnyInformationAboutWrongInput()
}
I think that it can help you.
^(?!-).*[a-zA-Z0-9-:#\\,()\/\\.]+$

Regex to match char after string

I'm attempting to match the first 3 letters that could be a-z followed by a specific character.
For testing I'm using a regex online tester.
I thought this should work (without success):
^[a-z]{0,3}$[z]
My test string is abcz.
Hope you can tell me what I'm doing wrong.
If you need to match a whole string abcz, use
/^[a-z]{0,3}z$/
^^
or - if the 3 letters are compulsory:
/^[a-z]{3}z$/
See the regex demo.
The $[z] in your pattern attempts to match a z after the end of string anchor, which makes the regex fail always.
Details:
^ - string start
[a-z]{0,3} - 0 to 3 lowercase ASCII letters (to require 3 letters, remove 0,)
z - a z
$ - end of string anchor.
You've got the end of line identifier too early
/^[a-z]{0,3}[z]$/m
You can see a working version here
You can do away with the [] around z. Square brackets are used to define a range or list of characters to match - as you're matching only one they're not needed here.
/^[a-z]{0,3}z$/m

Simple regex with repeated unordered matches

I have this regex
/^[a-z]{1,}( (?=[a-z])){0,}(_(?=[a-z])){0,}[a-z]{0,}$/
I want to match
ag_b_cf_ajk
or
zva b c de
or
hh_b opxop a_b
so any character tokens separated by a single space or underscore.
(In the regex above, we have a literal space, which is legal, and we have look-aheads that ensure that a space or underscore is followed by a character).
The problem is, my above regex is only matching the first space or underscore, like so:
axz_be
axz be
but these fail
axz_be_j
axz be j
I believe I missing some concept with regexes in order to solve this as I have been trying for the last few hours!
It seems you can just use
^[a-z]+(?:[_ ][a-z]+)*$
See the regex demo
The regex matches
^ - start of string
[a-z]+ - one or more lowercase ASCII letters
(?:[_ ][a-z]+)* - zero or more sequences of:
[_ ] - a space or an underscore
[a-z]+ - one or more lowercase ASCII letters
$ - end of string
If the space or underscore must appear at least once, use the + quantifier instead of *:
^[a-z]+(?:[_ ][a-z]+)+$
^
To add a multicharacter alternative to the underscore and hyphen, you need to introduce another non-capturing group:
^[a-z]+(?:(?:[_ ]|\[])[a-z]+)+$
See another regex demo

regex precceded by two or more special character

I am stuck with creating regex such that if the word is preceded or ended by special character more than one regex on each side regex 'exec' method should throw null. Only if word is wrap with exactly one bracket on each side 'exec' method should give result Below is the regular expression I have come up with.
If the string is like "(test)" or then only regex.exec should have values for other combination such as "((test))" OR "((test)" OR "(test))" it should be null. Below code is not throwing null which it should. Please suggest.
var w1 = "\(test\)";
alert(new RegExp('(^|[' + '\(\)' + '])(' + w1 + ')(?=[' + '\(\)' + ']|$)', 'g').exec("this is ((test))"))
If you have a list of words and want to filter them, you can do the following.
string.split(' ').filter(function(word) {
return !(/^[!##$%^&*()]{2,}.+/).test(word) || !(/[!##$%^&*()]{2,}$).test(word)
});
The split() function splits a string at a space character and returns an array of words, which we can then filter.
To keep the valid words, we will test two regex expressions to see if the word starts or ends with 2 or more special characters respectively.
RegEx Breakdown
^ - Expression starts with the following
[] - A single character in the block
!##$%^&*() - These are the special characters I used. Replace them with the ones you want.
{2,} - Matches 2 or more of the preceeding characters
.+ - Matches 1 or more of any character
$ - Expression ends with the following
To use the exec function this way do this
!(/^[!##$%^&*()]{2,}.+/).exec(string) || !(/[!##$%^&*()]{2,}$).exec(string)
If I understand correctly, you are looking for any string which contains (test), anywhere in it, and exactly that, right?
In that case, what you probably need is the following:
var regExp = /.*[^)]\(test\)[^)].*/;
alert(regExp.exec("this is ((test))")); // → null
alert(regExp.exec("this is (test))" )); // → null
alert(regExp.exec("this is ((test)" )); // → null
alert(regExp.exec("this is (test) ...")); // → ["this is (test) ..."]
Explanation:
.* matches any character (except newline) between zero and unlimited times, as many times as possible.
[^)] match a single character but not the literal character )
This makes sure there's your test string in the given string, but it is only ever wrapped with one brace in every side!
You can use the following regex:
(^|[^(])(\(test\))(?!\))
See regex demo here, replace with $1<span style="new">$2</span>.
The regex features an alternation group (^|[^(]) that matches either start of string ^ or any character other than (. This alternation is a kind of a workaround since JS regex engine does not support look-behinds.
Then, (\(test\)) matches and captures (test). Note the round brackets are escaped. If they were not, they would be treated as a capturing group delimiters.
The (?!\)) is a look-ahead that makes sure there is no literal ) right after test). Look-aheads are supported fully by JS regex engine.
A JS snippet:
var re = /(^|[^(])(\(test\))(?!\))/gi;
var str = 'this is (test)\nthis is ((test))\nthis is ((test)\nthis is (test))\nthis is ((test\nthis is test))';
var subst = '$1<span style="new">$2</span>';
var result = str.replace(re, subst);
alert(result);

regular expression to find word after a character and before another one if included

I have a url like:
image/media-group/rugby-league-programme-covers-3436?sort=title
or
image/media-group/rugby-league-programme-covers-3436
I need to get everything after media-group and not including ? or anything after.
So in both instances rugby-league-programme-covers-3436 is what I need to return
I used the regular expression /media-group/(.*)\? which works for the instance where there is a query string but not in the instance where there is no query string.
I am using the below code
var patt=new RegExp('/media-group/(.*)\?');
return patt.exec(url)[1];
Your help on this would be most appreciated
I believe the best pattern would be:
/^[^\#\?]+\/media-group\/([^\?]+).*$/
which breaks out as:
^ - start of string
[^\#\?]+ - one or more non-hash, non-question-marks
\/ - literal char
media-group - literal chars
\/ - literal char
( - start capture group
[^\?]+ - one or more chars non-question-marks
) - end of capture group
.* - zero or more chars
$ - end of string
The reason this works is because [^\?]+ is "greedy" in that it will attempt the longest possible match, which encompasses either a question-mark followed by arbitrary chars, or nothing, since all chars to the end of the string have already been captured in the non-question-mark capture group.
So, using
var RE=new RegExp(/^[^\#\?]+\/media-group\/([^\?]+).*$/),
url="image/media-group/rugby-league-programme-covers-3436?sort=title";
console.log(url.match(RE)[1])
prints: rugby-league-programme-covers-3436 and changing url to image/media-group/rugby-league-programme-covers-3436, produces the same result.
Update
Modified the pattern re David Foerster's comment.

Categories