Another regex expression - regex

I need a regular expression for the next rules:
should not start or end with a space
should contain just letters (lower / upper), digits, #, single quotes, hyphens and spaces (spaces just inside, but not at the beginning and the end, as I already said)
should contain at least one letter (lower or upper).
Thank you

I think
^[^ ](?=.*[a-zA-Z]+)[a-zA-Z0-9#'\- ]*[^ ]$
should help you.

"Does it really matter guys?"
with regards to the dialect of regex: yes it does matter. Different languages may have different dialects. One example off the top of my head is that the RegEx library in PHP supports lookbehinds whereas RegEx library in JavaScript does not. This is why it is important for you to list the underlying language that you're using. Also for future reference, it is helpful for those wanting to answer your questions to provide us with sample input and sample matches from the input.
Using the information that you provided, this is also a question that I feel as though you should use RegEx and JavaScript to validate the input. Take a look at this example:
window.onload = function() {
var valid = "a1 - 'super' 1";
var invalid1 = " a1 - 'super' 1"; //leading ws
var invalid2 = "a1 - 'super' 1 "; //trailing ws
var invalid3 = "a1 - 'super' 1?"; //invalid (?) char
var invalid4 = "1 - '123'"; //no letters
console.log(valid + ": " + validation(valid));
console.log(invalid1 + ": " + validation(invalid1));
console.log(invalid2 + ": " + validation(invalid2));
console.log(invalid3 + ": " + validation(invalid3));
}
function validation(input) {
var acceptableChars = new RegExp(/[^a-zA-Z\d\s'-]/g);
var containsLetter = new RegExp(/[a-zA-Z]/);
return input.length > 1 && input.trim().length == input.length && !acceptableChars.test(input) && containsLetter.test(input);
}

Related

RegEx for matching the first {N} chars and last {M} chars

I'm having an issue filtering tags in Grafana with an InfluxDB backend. I'm trying to filter out the first 8 characters and last 2 of the tag but I'm running into a really weird issue.
Here are some of the names...
GYPSKSVLMP2L1HBS135WH
GYPSKSVLMP2L2HBS135WH
RSHLKSVLMP1L1HBS045RD
RSHLKSVLMP35L1HBS135WH
RSHLKSVLMP35L2HBS135WH
only want to return something like this:
MP8L1HBS225
MP24L2HBS045
I first started off using this expression:
[MP].*
But it only returns the following out of 148:
PAYNKSVLMP27L1HBS045RD
PAYNKSVLMP27L1HBS135WH
PAYNKSVLMP27L1HBS225BL
PAYNKSVLMP27L1HBS315BR
The pattern [MP].* Matches either a M or P and then matches any char until the end of the string not taking any char, digit or quantifing number afterwards into account.
If you want to match MP and the value does not end on a digit but the last in the match should be a digit, you could use:
MP[A-Z0-9]+[0-9]
Regex demo
If lookaheads are supported you might also use:
MP[A-Z0-9]+(?=[A-Z0-9]{2}$)
Regex demo
You may not even want to touch MP. You can simply define a left and right boundary, just like your question asks, and swipe everything in between which might be faster, maybe an expression similar to:
(\w{8})(.*)(\w{2})
which you can simply call it using $2. That is the second capturing group, just to be easy to replace.
Graph
This graph shows how the expression would work:
Performance
This JavaScript snippet shows the performance of this expression using a simple 1-million times for loop.
repeat = 1000000;
start = Date.now();
for (var i = repeat; i >= 0; i--) {
var string = "RSHLKSVLMP35L2HBS135WH";
var regex = /^(\w{8})(.*)(\w{2})$/g;
var match = string.replace(regex, "$2");
}
end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match 💚 ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. 😳 ");
Try Regex: (?<=\w{8})\w+(?=\w{2})
Demo

Regex To Match Comma Separated Values Between Round Brackets [duplicate]

I am trying to write a regular expression which returns a string which is between parentheses. For example: I want to get the string which resides between the strings "(" and ")"
I expect five hundred dollars ($500).
would return
$500
Found Regular expression to get a string between two strings in Javascript
I don't know how to use '(', ')' in regexp.
You need to create a set of escaped (with \) parentheses (that match the parentheses) and a group of regular parentheses that create your capturing group:
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec("I expect five hundred dollars ($500).");
//matches[1] contains the value between the parentheses
console.log(matches[1]);
Breakdown:
\( : match an opening parentheses
( : begin capturing group
[^)]+: match one or more non ) characters
) : end capturing group
\) : match closing parentheses
Here is a visual explanation on RegExplained
Try string manipulation:
var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var newTxt = txt.split('(');
for (var i = 1; i < newTxt.length; i++) {
console.log(newTxt[i].split(')')[0]);
}
or regex (which is somewhat slow compare to the above)
var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var regExp = /\(([^)]+)\)/g;
var matches = txt.match(regExp);
for (var i = 0; i < matches.length; i++) {
var str = matches[i];
console.log(str.substring(1, str.length - 1));
}
Simple solution
Notice: this solution can be used for strings having only single "(" and ")" like string in this question.
("I expect five hundred dollars ($500).").match(/\((.*)\)/).pop();
Online demo (jsfiddle)
To match a substring inside parentheses excluding any inner parentheses you may use
\(([^()]*)\)
pattern. See the regex demo.
In JavaScript, use it like
var rx = /\(([^()]*)\)/g;
Pattern details
\( - a ( char
([^()]*) - Capturing group 1: a negated character class matching any 0 or more chars other than ( and )
\) - a ) char.
To get the whole match, grab Group 0 value, if you need the text inside parentheses, grab Group 1 value.
Most up-to-date JavaScript code demo (using matchAll):
const strs = ["I expect five hundred dollars ($500).", "I expect.. :( five hundred dollars ($500)."];
const rx = /\(([^()]*)\)/g;
strs.forEach(x => {
const matches = [...x.matchAll(rx)];
console.log( Array.from(matches, m => m[0]) ); // All full match values
console.log( Array.from(matches, m => m[1]) ); // All Group 1 values
});
Legacy JavaScript code demo (ES5 compliant):
var strs = ["I expect five hundred dollars ($500).", "I expect.. :( five hundred dollars ($500)."];
var rx = /\(([^()]*)\)/g;
for (var i=0;i<strs.length;i++) {
console.log(strs[i]);
// Grab Group 1 values:
var res=[], m;
while(m=rx.exec(strs[i])) {
res.push(m[1]);
}
console.log("Group 1: ", res);
// Grab whole values
console.log("Whole matches: ", strs[i].match(rx));
}
Ported Mr_Green's answer to a functional programming style to avoid use of temporary global variables.
var matches = string2.split('[')
.filter(function(v){ return v.indexOf(']') > -1})
.map( function(value) {
return value.split(']')[0]
})
Alternative:
var str = "I expect five hundred dollars ($500) ($1).";
str.match(/\(.*?\)/g).map(x => x.replace(/[()]/g, ""));
→ (2) ["$500", "$1"]
It is possible to replace brackets with square or curly brackets if you need
For just digits after a currency sign : \(.+\s*\d+\s*\) should work
Or \(.+\) for anything inside brackets
let str = "Before brackets (Inside brackets) After brackets".replace(/.*\(|\).*/g, '');
console.log(str) // Inside brackets
var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/;
alert(rex.exec(str));
Will match the first number starting with a $ and followed by ')'. ')' will not be part of the match. The code alerts with the first match.
var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/g;
var matches = str.match(rex);
for (var i = 0; i < matches.length; i++)
{
alert(matches[i]);
}
This code alerts with all the matches.
References:
search for "?=n"
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
search for "x(?=y)"
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp
Simple:
(?<value>(?<=\().*(?=\)))
I hope I've helped.

Regexp help - is this possible at all with regexp?

I'm still struggling with regexp, wondering if this is at all possible.
I need to parse variable names from expression, but I need to skip ones within string literals and ones after "dot".
so for expression like:
'test' + (n + text.length)
I would like to get only n and text.
I'm using /([a-z_][a-z0-9_]*)/gi
but it gives me test,n,text,length
Thanks for help:)
If your input is not too complicated, here is a possible regex option:
var re = /'[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|(?:^|[^.])\b(\w+)/g;
var str = '\'test\\\' this\' + "Missing \\\"here\\\"" + (n + text.length)';
document.body.innerHTML = "Testing string: <b>" + str + "</b><br/>";
var res = [];
while ((m = re.exec(str)) !== null) {
if (m[1]) { res.push(m[1]); }
}
document.body.innerHTML += JSON.stringify(res, 0, 4);
The regex details:
'[^'\\]*(?:\\.[^'\\]*)*' - single quoted string literals (supporting escaped sequences)
| - or
"[^"\\]*(?:\\.[^"\\]*)*" - double quoted string literals (supporting escaped sequences)
| - or
(?:^|[^.])\b(\w+) - 1+ word characters that are either right at the string start or after a non-dot and preceded with a word boundary (placed inside Group 1)
See the regex demo.

Regex for multiple strings including spaces

I need a regex for filtering out a query. For example, I get a query input as below.
state:CA AND country:US OR postalcode:8888
Here, I need to extract terms based on " AND ", " OR " (any case). Can someone please provide the regex with which I can extract terms like "state:CA", "country:US" etc?
I want to consider the spaces before and after the AND, OR as the other terms might contain "and", "or" as part of string.
Eg: state:OR AND country:US
UPDATE:
I have tried something like this
\sAND\s|\sOR\s
With this, I could find the patterns " AND ", " OR ". But, how to make it case-insensitive?
What flavor or regex are you using ?
If the value in your key/pair values will always be comprised of one word only, this would do:
\w+:\w+
Test it here.
Update:
Since your values are comprised by more than one word only, I think you should be splitting the string into key/value pairs instead of using regexes.
Here's how you could do it in javascript:
var s = 'state:New York AND country:US OR postalcode:8888'
var dataBlocks = s.replace(/AND|and|And|OR|Or/g, '|').split('|')
for(var i = 0; i < dataBlocks.length; i++) dataBlocks[i] = dataBlocks[i].trim()
//your resulting array would like like
//Array [ "state:New York", "country:US", "postalcode:8888" ]
The same solution, in C#:
Regex r = new Regex(#"AND|and|And|OR|Or");
var s = "state:New York AND country:US OR postalcode:8888";
var keyValuePairs = r.Replace(s, "|").Split(new char[] { '|' }).Select(z =>
{
var keyValue = z.Trim().Split(new char[] { ':' });
return new KeyValuePair<string, string>(keyValue.FirstOrDefault(), keyValue.LastOrDefault());
});
foreach (var keyValuePair in keyValuePairs)
Console.WriteLine("Key: {0}\tValue:{1}", keyValuePair.Key, keyValuePair.Value);

regex how can I split this word?

I have a list of several phrases in the following format
thisIsAnExampleSentance
hereIsAnotherExampleWithMoreWordsInIt
and I'm trying to end up with
This Is An Example Sentance
Here Is Another Example With More Words In It
Each phrase has the white space condensed and the first letter is forced to lowercase.
Can I use regex to add a space before each A-Z and have the first letter of the phrase be capitalized?
I thought of doing something like
([a-z]+)([A-Z])([a-z]+)([A-Z])([a-z]+) // etc
$1 $2$3 $4$5 // etc
but on 50 records of varying length, my idea is a poor solution. Is there a way to regex in a way that will be more dynamic? Thanks
A Java fragment I use looks like this (now revised):
result = source.replaceAll("(?<=^|[a-z])([A-Z])|([A-Z])(?=[a-z])", " $1$2");
result = result.substring(0, 1).toUpperCase() + result.substring(1);
This, by the way, converts the string givenProductUPCSymbol into Given Product UPC Symbol - make sure this is fine with the way you use this type of thing
Finally, a single line version could be:
result = source.substring(0, 1).toUpperCase() + source(1).replaceAll("(?<=^|[a-z])([A-Z])|([A-Z])(?=[a-z])", " $1$2");
Also, in an Example similar to one given in the question comments, the string hiMyNameIsBobAndIWantAPuppy will be changed to Hi My Name Is Bob And I Want A Puppy
For the space problem it's easy if your language supports zero-width-look-behind
var result = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "(?<=[a-z])([A-Z])", " $1");
or even if it doesn't support them
var result2 = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "([a-z])([A-Z])", "$1 $2");
I'm using C#, but the regexes should be usable in any language that support the replace using the $1...$n .
But for the lower-to-upper case you can't do it directly in Regex. You can get the first character through a regex like: ^[a-z] but you can't convet it.
For example in C# you could do
var result4 = Regex.Replace(result, "^([a-z])", m =>
{
return m.ToString().ToUpperInvariant();
});
using a match evaluator to change the input string.
You could then even fuse the two together
var result4 = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "^([a-z])|([a-z])([A-Z])", m =>
{
if (m.Groups[1].Success)
{
return m.ToString().ToUpperInvariant();
}
else
{
return m.Groups[2].ToString() + " " + m.Groups[3].ToString();
}
});
A Perl example with unicode character support:
s/\p{Lu}/ $&/g;
s/^./\U$&/;