Botkit for Slack using regex patterns in conversations - regex

I'm running into an issue using regex patterns in botkit conversations that I can't quite work through, and though I'm sure someone else will have a quick answer, I'm utterly stumped.
I'm building a conversation that will store user information in a JSON file, but I need a small amount of validation on the entries before I store them. Specifically, the inputs must either be a full name (any number of words greater than one with a space between them) or a domain username in the format of domain\name with no spaces and the correct domain.
Using RegExr, I came up with the following regEx expressions which match in that user interface but which will not match when placed in the "pattern" attribute of the botkit conversation node:
\w+( +\w+)+ for the any number of words with a space between them.
domain+(\\+\w+) for the specified domain + a username
But when I use these in the botkit conversation, they're not matching -- so I'm not quite clear on what I'm doing wrong.
Here's the code snippet in which these are being used:
bot.startConversation(message, function (err, convo) {
convo.say("I don't know who you are in TFS. Can you tell me?");
convo.addQuestion("You can say \"no\" or tell me your TFS name or your domain name (eg: \"domain\\username)", [
{
pattern: bot.utterances.no,
callback: function (response, convo) {
convo.say("Okay, maybe another time then.");
convo.next();
}
},
{
pattern: '\w+( +\w+)+',
callback: function (response, convo) {
convo.say("You said your TFS name is " + response.text);
convo.next();
}
},
{
pattern: 'domain+(\\+\w+)+',
callback: function (response, convo) {
convo.say("You said your TFS name is " + response.text);
convo.next();
}
},
{
default: true,
callback: function (response, convo) {
convo.say("I didn't understand that.");
convo.repeat();
convo.next();
}
}
], {}, 'default');

You need to use double backslashes, and fix the backslash before the closing single quote in the first regex string literal:
pattern: '\\w+( +\\w+)+',
pattern: 'domain(\\\\\\w+)+',
The first pattern:
\\w+ - 1+ word chars
( +\\w+)+ - 1 or more sequences of 1 or more spaces and then 1 or more word chars
Domain regex:
domain - a domain
(\\\\\\w+)+ - 1 or more occurrences of
\\\\ - 1 backslash
\\w+ - 1 or more word chars.

Related

Validation for Telephone filed with regular expression in react native

I want to restrict user from entering any special character in Input field apart from first character as + and total number of character not more than 15. I want to check it using regular expression on onChangeText in react native. If user another + then it should restrict it.
I am using below expression which accepts only numbers but now I want it to accept first character as +.
export default (val) => {
return val.replace(/\D+/g, '')
}
You may use
export default (val) => {
return val.replace(/^(\+)|\D/g, '$1')
}
See the regex demo and the regex graph:
The regex matches and captures into Group 1 a + at the start of the string or any non-digit char in all other contexts and the match is replaced with the contents of Group 1. So, if there is a + at the start, it will be put back into the resulting string, else, it will be removed from the string.

RegEx for Matching Numeric Patterns With or Without Dashes

Are Email Host has a back end Archiving platform. I asked them if we could be alerted if certain formats are located within the Email and they asked me to submit them a RegEx Query String so they can put it into there system. I Know there Main Email System is Exchange, how ever I am not sure what there backend is.... I am assuming exchange and I apologize for I did not even think to ask for that piece of info.
NEED TO LOOK FOR THE FOLLOWING DIGIT PATTERNS (which is for Social Security # Formats)
9 digit formats:
XXX-XX-XXXX
XXXXXXXXX
XX-XXXXXXX
NEED TO LOOK FOR THE FOLLOWING DIGIT PATTERNS (which is for Customer Acct # Formats)
8 digit formats:
xxxxxxxx
I have not tried anything for I am not sure on how to test with out submitting to my host. But this is what I cam up with Two stings to accomplish the task for both 8 and 9 digit patterns
Regex.Match([/d]+[/d]+\-?[/d]+\-?[/d]+[/d-]+\-?[/d]+[/d]+[/d]+[/d]);
``
Regex.Match([/d]+[/d]+[/d]+[/d]+[/d]+[/d]+[/d]+[/d]);
I would expect the output to be any email that matches the numeric sequence pattern
I would use the following regex pattern, which is an alternation of three terms:
\d{8}\d?|\d{3}-\d{2}-\d{4}|\d{2}-\d{7}
Demo
Note that a single digit in regex is represented by \d, with a single backslash, not a forward slash.
Just for simplicity, you might want to design an easy expression, maybe something similar to this, to be easy to be changed whenever you wish:
([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})|([0-9]{8})
It has four groups for each of your numbers:
([0-9]{3}-[0-9]{2}-[0-9]{4}) for SSN type 1
([0-9]{9}) for SSN type 2
([0-9]{2}-[0-9]{7}) for SSN type 3
([0-9]{8}) which is for customer account number
You can simply join this groups with an OR:
([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})|([0-9]{8})
If you wish to have two separate expressions, you might want to join the first two:
([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})
and your second expression would work as:
([0-9]{8})
You can add additional boundaries to it if you wish. For example, you can bound them with start and end chars:
Both RegEx:
^([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})|([0-9]{8})$
SSN RegEx:
^([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})$
Customer Account RegEx:
^([0-9]{8})$
Graph
This graph shows how the expression would work and you can visualize other expressions in this link:
JavaScript Testing
const regex = /([0-9]{3}-[0-9]{2}-[0-9]{4})|([0-9]{9})|([0-9]{2}-[0-9]{7})|([0-9]{8})/gm;
const str = `111-22-3333
111223333
11-1234567
12345678`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}

Regex: match only line where numbers are located

Really tired of this regex. So many combinations.... I believe I need another brain :-)
Here is my problem and if someone help, I'd be highly appreciated.
I have those 6 lines of JSON response
...some JSON code here
"note" : "",
"note" : "Here is my note",
"note" : "My note $%$",
"note" : "Created bug 14569 in the system",
"note" : "Another beautiful note",
"note" : "##$%##%dgdeg"
...continuation of the JSON code
With the help of Regex, how do I match number 14569 only?
I have tried this regex, but it matches all 6 lines
"note"([\s\:\"a-zA-Z])*([0-9]*) - 6 matches (I only need one)
"note"([\s\:\"a-zA-Z])*(^[0-9]*) - no matches
"note"([\s\:\"a-zA-Z])*([0-9]*+?) - pattern error
"note"([\s\:\"a-zA-Z])*(^[0-9]*+#?) - no match
Thanks for you help!
Updated for Matt. Below is my full JSON object
"response": {
"notes": [{
"note" : "",
"note" : "Here is my note",
"note" : "My note $%$",
"note" : "Created bug 14569 in the system",
"note" : "Another beautiful note",
"note" : "##$%##%dgdeg"
}]
}
You could try this regex:
"note"\s*:\s*".*?([0-9]++).*"
It will give you the number in group 1 of the match.
If you don't want to match numbers that are part of a word (e.g. "bug11") then surround the capture group with word boundary assertions (\b):
"note"\s*:\s*".*?\b([0-9]++)\b.*"
Regex101 demo
If all that you care about is that the line includes a number, then that is all you need to look for.
/[0-9]/ # matches if the string includes a digit
Or, as you want to capture the number:
/([0-9]+)/ # matches (and captures) one or more digits
This is a common error that I see when beginners build regular expressions. They want to build a regex that matches the whole string - when, actually, they only need to match the bit of the string that they want to match.
Update:
It might help to explain why some of your other attempts failed.
"note"([\s\:\"a-zA-Z])*([0-9]*) - 6 matches (I only need one)
The * means "match zero or more of the previous item", effectively making the item optional. This matches all lines as they all contain zero or more digits.
"note"([\s\:\"a-zA-Z])*(^[0-9]*) - no matches
The ^ means "the next item needs to be at the start of the string". You don't have digits at the start of your string.
"note"([\s\:\"a-zA-Z])*([0-9]*+?) - pattern error
Yeah. You're just adding random punctuation here, aren't you? *+? means nothing to the regex parser.
"note"([\s\:\"a-zA-Z])*(^[0-9]*+#?) - no match
This fails for the same reason as the previous attempt where you use ^ - the digits aren't at the start of the string. Also, the # has no special meaning in a regex, so #? means "zero or one # characters".
If you have JSON, why don't you parse the JSON and then grep through the result?
use JSON 'decode_json';
my $data = decode_json( $json_text );
my #rows = map { /\b(\d+)\b/ ? $1 : () } # keep only the number
map { $_->{note} } #$data;
This might work (?m-s)^[^"\r\n]*?"note"\h*:\h*"[^"\r\n]*?\d+[^"\r\n]*".*
https://regex101.com/r/ujDBa9/1
Explained
(?m-s) # Multi-line, no dot-all
^ # BOL
[^"\r\n]*? # Not a double quote yet
"note" \h* : \h* # Finally, a note
" [^"\r\n]*? \d+ [^"\r\n]* " # Is a number embedded within the quotes ?
.* # Ok, get the rest of the line

JQuery + Regex: Grouping and Counting

I have been reading and playing with regex used in JQuery, and have got things partially working but don't seem to be tracking on the failing regex.
The specific problem – I think – has to do with 'look[ing]behind'.
Thanks to CodeJockey for the original direction. Here's my updated code:
<script type="text/javascript">
jQuery(document).ready(function($) {
$.validator.addMethod("lccharReqs", function(value, element) {
var lc = /(?=.*[a-z])/;
return this.optional(element) || lc.test(value);
}, "Your password should contain at least one lowercase letter!");
$.validator.addMethod("uccharReqs", function(value, element) {
var uc = /(?=.*[A-Z])/;
return this.optional(element) || uc.test(value);
}, "Your password should contain at least one uppercase letter!");
$.validator.addMethod("nccharReqs", function(value, element) {
var nc = /(?=.*[0-9])/;
return this.optional(element) || nc.test(value);
}, "Your password should contain at least one number!");
$.validator.addMethod("speccharReqs", function(value, element) {
var sc = /(?<=.*[\!\#\#\$\%\&\?\-\_])/;
return this.optional(element) || sc.test(value);
}, "Your password should contain at least one special character!");
$("#new_noisuf_pwd").validate({
rules: {
inf_field_Password: {
required: true,
minlength: 8,
lccharReqs: true,
uccharReqs: true,
nccharReqs: true,
speccharReqs: true
},
pwd_confirm : {
equalTo: "#inf_field_Password"
}
},
messages: {
inf_field_Password: {
required: "Please enter a password!",
minlength: "Your password must be at least 8 characters!",
maxlength: "Your password cannot be more the 12 characters!"
},
pwd_confirm : {
equalTo: "Your passwords does not match!"
}
}});
});
</script>
The reason I'm leaning towards the 'lookbehind' is:
Enter aaaaaaaa - I get the uppercase error...
Enter Aaaaaaaa - I get the number error...
Enter 1Aaaaaaa - I get the special character error, but
Enter Passw0rd - I get no error.
Really trying to learn this and have been reading a lot, but I'm stuck.
Thanks!
[original question]
I am using the 'validation' plugin and am adding a method as follows:
jQuery.validator.addMethod("charReqs", function(value, element) {
return this.optional(element) || /^(([a-z]{1})([A-Z]{1})([0-9]{1})([\!\#\#\+\-]{1})) *$/.test(value);
}, "One lowercase letter, one capital letter, one number and one of the characters listed above - please!");
1.) Do I have the syntax correct to check for 1 l-c char, 1 u-c char, 1 num and 1 of a list of special chars somewhere in the string:
/^ ( ([a-z]{1}) ([A-Z]{1}) ([0-9]{1}) ([\!\#\#\+\-]{1}) ) *$/
2.) Am I grouping this correctly?
3.) If not, please explain.
Thanks
POINT BY POINT ANSWER
1) Not really, no
Your expression specifies a string that begins with exactly one lower case character [a-z], followed by exactly one upper case character[A-Z], followed by exactly one digit [0-9], followed by exactly one of the following characters: !, #, #, +, -, followed by zero or more spaces, then the end of the string :-/
2) Nope - not grouped correctly
3) More complex explanation: the character classes ([a-z], [0-9], etc) are correct enough (though the {1} part and escaping \ characters are redundant. However, you need to have them in what's called a "lookahead" that matches matching anything followed by those characters.
Instead of saying "match one of these"
([a-z])
You would say essentially "lookahead and see if you can match any text followed by one of these, then come back"
(?=.*[a-z])
To match two characters somewhere in the string, you would do like this:
(?=(.*[a-z]){2})
As for the whole expression, to match one of each of the characters you were looking for, use this:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\!\#\#\+\-])$
To require two or more of each, you would use the {#} notation, like
^(?=(.*[a-z]){2})(?=(.*[A-Z]){2})(?=(.*[0-9]){2})(?=(.*[\!\#\#\+\-]){2})$
You could also enforce a minimum length (like 10 characters) like
^(?=(.*[a-z]){2})(?=(.*[A-Z]){2})(?=(.*[0-9]){2})(?=(.*[\!\#\#\+\-]){2}).{10,}$
HOWEVER
I would recommend separating these out into separate expressions (I'm guessing something like jQuery.validator.addMethod("...", function(...){...}, "Reason...").addMethod(...).addMethod(...).etc() that each tell the user what's missing. So you'd have one looking for lowercase characters, saying "you need a lower case character", then one looking for digits saying "you need a digit", etc...
Also, the special characters there are really restrictive, so I hope you allow some other ones as well (as long as those are provided (?))
and finally... see http://xkcd.com/936/

How does Sencha Touch matcher work?

I am trying to create a simple matcher that matches any string consisting of alphanumeric characters. I tried the following:
Ext.regModel('RegistrationData', {
fields: [
{name: 'nickname',type: 'string'},
],
validations: [
{type: 'format', name: 'nickname', matcher: /[a-zA-Z0-9]*/}
]
});
However this does not work as expected. I did not find any documentation on how should a regular expression in a matcher look like.
Thank you for help.
I found a blog on sencha.com, where they explain the validation.
I have no idea what sencha-touch is, but maybe it helps, when you tell us what you are giving to your regex, what you expect it to do, and what it actually does (does not work as expected is a bit vague). According to the blog it accepts "regular expression format", so for your simple check, it should be pretty standard.
EDIT:
As a wild guess, maybe you want to use anchors to ensure that the name has really only letters and numbers:
/^[a-zA-Z0-9]*$/
^ is matching the start of the string
$ is matching the end of the string
Your current regex /[a-zA-Z0-9]*/ would match a string containing zero or more occurrences of lower or upper case characters (A-Z) or numbers anywhere in the string. That's why Joe#2, J/o/e, *89Joe as well as Joe, Joe24andjOe28` match - they all contain zero or more subsequent occurrences of the respective characters.
If you want your string to contain only the respective characters you have to change the regex according to stema's answer:
/^[a-zA-Z0-9]*$/
But this has still one problem. Due to the * which meas zero or more occurrences it also matches an empty string, so the correct string should be:
/^[a-zA-Z0-9]+$/
with + meaning one or more occurrences. This will allow nicknames containing only one lowercase or uppercase character or number, such as a, F or 6.