HipChat Bot JS REGEX - javascript

I'm completely useless with Regular expressions and need help with this one. I'm currently creating a HipChat bot for my work which will create JIRA tickets from HipChat.. HipChat bots have the ability to monitor a chat room for keywords.. then run JavaScript if the keyword has been used.
In my case, I would like the Bot to monitor for -
"/ask ********************************"
Where * = text of the JIRA issue body of unlimited length
so for this, i would need regex to hook on to, and also regex to move the description text into a variable.. would anyone here be able to assist??
If I haven't explained myself well, below is an example of how "Karma" works (addon.webhook). Thanks!
https://bitbucket.org/atlassianlabs/ac-koa-hipchat-karma/src/cca57e089a2f630d924cd5df23211f0da3617063/web.js?at=master

You could simply use this regex:
^\/ask (.*)$
It will capture the text after /ask. Note the escaped backslash here as well. Since you're using Javascript, the actual expression is used with delimiters, e.g.:
/^\/ask (.*)$/
Here's a regex101 to play with: https://regex101.com/r/tZ0iB6/1

It's a quiet simple regex:
var matches = /^\/ask\s+(.*)$/i.exec(str);
if (matches && matches.length > 0) {
var content = matches[1];
}
If you want to match multiple different command you can use something like this:
var matches = /^\/([^\s]+)\s+(.*)$/g.exec(str);
if (matches && matches.length > 0) {
var command = matches[1];
var content = matches[2];
switch(command.toLowerCase()) {
case 'ask':
// do something
break;
default:
// command not found
break;
}
}
Edit:
Fixed the 'a' variable
the variable str has to be the input string.
var str = '/ask *****';

Related

Regex to match #word [duplicate]

I am writing an application in Node.js that allows users to mention each other in messages like on twitter. I want to be able to find the user and send them a notification. In order to do this I need to pull #usernames to find mentions from a string in node.js?
Any advice, regex, problems?
I have found that this is the best way to find mentions inside of a string in javascript.
var str = "#jpotts18 what is up man? Are you hanging out with #kyle_clegg";
var pattern = /\B#[a-z0-9_-]+/gi;
str.match(pattern);
["#jpotts18", "#kyle_clegg"]
I have purposefully restricted it to upper and lowercase alpha numeric and (-,_) symbols in order to avoid periods that could be confused for usernames like (#j.potts).
This is what twitter-text.js is doing behind the scenes.
// Mention related regex collection
twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*#@]|RT:?)/;
twttr.txt.regexen.atSigns = /[#@]/;
twttr.txt.regexen.validMentionOrList = regexSupplant(
'(#{validMentionPrecedingChars})' + // $1: Preceding character
'(#{atSigns})' + // $2: At mark
'([a-zA-Z0-9_]{1,20})' + // $3: Screen name
'(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?' // $4: List (optional)
, 'g');
twttr.txt.regexen.endMentionMatch = regexSupplant(/^(?:#{atSigns}|[#{latinAccentChars}]|:\/\/)/);
Please let me know if you have used anything that is more efficient, or accurate. Thanks!
Twitter has a library that you should be able to use for this. https://github.com/twitter/twitter-text-js.
I haven't used it, but if you trust its description, "the library provides autolinking and extraction for URLs, usernames, lists, and hashtags.". You should be able to use it in Node with npm install twitter-text.
While I understand that you're not looking for Twitter usernames, the same logic still applies and you should be able to use it fine (it does not validate that extracted usernames are valid twitter usernames). If not, forking it for your own purposes may be a very good place to start.
Edit: I looked at the docs closer, and there is a perfect example of what you need right here.
var usernames = twttr.txt.extractMentions("Mentioning #twitter and #jack")
// usernames == ["twitter", "jack"]
here is how you extract mentions from instagram caption with JavaScript and underscore.
var _ = require('underscore');
function parseMentions(text) {
var mentionsRegex = new RegExp('#([a-zA-Z0-9\_\.]+)', 'gim');
var matches = text.match(mentionsRegex);
if (matches && matches.length) {
matches = matches.map(function(match) {
return match.slice(1);
});
return _.uniq(matches);
} else {
return [];
}
}
I would respect names with diacritics, or character from any language \p{L}.
/(?<=^| )#\p{L}+/gu
Example on Regex101.com with description.
PS:
Don't use \B since it will match ##wrong.

Remove a href tags from a string using regex

Hey this may have been asked elsewhere somewhere but i couldnt seen to find it.
Essentially im just trying to remove the a tags from a string using regex in javascript.
So i have this:
This is google
and i want the output to just be "this is google".
How would this be done in javascript using regex?
Thanks in advance!!
SOLUTION:
Ok so the solution i was provided from my boss goes as follows
The best way to do that is in two parts. One is to remove all closing tags. Then you’re going to want to focus on removing the opening tag. Should be as straightforward as:
/<a\s+.*?>(.*)<\/a>/
With the .*? being the non-greedy version of match /anything/
This shouldn't be done with regex at all, but like this for example:
var a = document.querySelectorAll('a');
var texts = [].slice.call(a).map(function(val){
return val.innerHTML;
});
console.log(texts);
this is google
If you only have the a string with multiple <a href...>, you can create an element first
var a_string = 'this is googlethis is yahoo',
el = document.createElement('p');
el.innerHTML = a_string;
var a = el.querySelectorAll('a');
var texts = [].slice.call(a).map(function(val){
return val.innerHTML;
});
console.log(texts);
I don't know your case, but if you're using javascript you might be able to get the inside of the element with innerHTML. So, element.innerHTML might output This is google.
The reasoning is that Regex really isn't meant to parse HTML.
If you really, really want a Regexp, here you go:
pattern = />(.*)</;
string = 'This is google';
matches = pattern.exec(string);
matches[1] => This is google
This uses a match group to get the stuff inside > and <. This won't work with every case, I guarantee it.
Try this with lookahead.Get the first capturing group.
(?=>).([^<]+)
Check Demo
One more way, with using of capturing groups. So, you basically match all, but grab just one result:
var re = /<a href=.+>(.+)<\/a>/;
var str = 'this is google';
var m;
if ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
}
console.log(m[1]);
https://regex101.com/r/rL0bT6/1 Note: code created by regex101.
Demo:http://jsfiddle.net/ry83mhwc/

Regular expression to find file name using any Javascript based library

I am working with markdown editor. After user uploads an image I see following line being entered on the editor.
![](/assets/img/content/id/2e65c657cf609fca24893278cdcb2159.gif)
What I want is: I want to extract the file name by searching content of entire editor.
assume I have following content on my editor:
Hello world.pdf
![](/assets/img/content/id/2e65c657cf609fca24893278cdcb2159.gif)
This is a test
![](/assets/img/content/id/2e65c657cf609fcaeqwe78cdcb2159.png)adding text
Adding another image
![](/assets/img/content/id/2e65c657cf609f24432434423b2159.jpg)
From the above content, after running the regular expression, I should be able to get:
2e65c657cf609fca24893278cdcb2159.gif
2e65c657cf609fcaeqwe78cdcb2159.png
2e65c657cf609f24432434423b2159.jpg
I have tried something like this. Though its working, I am not sure its the best solution:
var myregex = /\(\/assets\/img\/content\/id\/(.+?)\)/gm
var result, allMatches = [];
while((result = myregex.exec(data)) != null) {
var match = result[1]; // get the first match pattern of this match
allMatches.push(match);
}
Use following regex:
var fileNames = content.match(/(\w+\.[a-z]{3,4})/gi);
REGEX Explanation
/: Delimiters of regex
(): Capturing Group
\w+: Matches one or more of any alphabetical character and _(underscore)
\.: Matches . literal
[a-z]{3,4}: Matches 3 to 4 alphabets
gi: Match all occurrences g and case insensitive i
DEMO
JsFiddle DEMO
UPDATE
var fileNames = content.match(/\!\[\].*?(\w+\.[a-z]{3,4})/gi);
fileNames = fileNames.toString();
var names = fileNames.match(/\w+\.[a-z]{3,4}/gi);
alert(names);
DEMO
Try this (for images)
/(\w+\.(?:gif|png|jpe?g))/gi
demo
or for any file type
/(\w+\.(?:\w{2,4}))/gi
demo
UPDATE
Based on comments made on #Tushar's answer
(?:\/assets\/img\/content\/id\/)(\w+\.(?:\w{2,4}))
will find any file with the preceding path /assets/img/content/id/. As one of the tags stated javascript we cannot use a positive lookbehind
demo

Javascript Regular Expressions Capture

I need to capture this: <!.This is a string.!>
It can contain anything within the <!. .!>
So I tried this: <\!\..+\.\!>/g
Which didn't work. I've been trying to fix this for days now with no success. I want to capture the whole string including the <!. .!>
Thanks for the help!
EDIT
Since the OP edited his post to specify that he doesn't just want to capture the string but also the delimiters, I have moved out the capturing parentheses from <!\.(.*?)\.!> to (<!\..*?\.!>)
This should do it:
var myregexp = /(<!\..*?\.!>)/m;
var match = myregexp.exec(subject);
if (match != null) {
result = match[1];
} else {
result = "";
}
Since JS does not support lookbehinds, the idea is to match the whole string, including the delimiters, but to only capture "My String" into Group 1. Then we inspect Group 1.
For someone that's "pretty good at Regex", this one is a no brainier.
var subject = "<!.This is a string.!>";
subject = subject.match(/<!\.(.*?)\.!>/);
console.log(subject[1]);
http://jsfiddle.net/tuga/YzLnN/1/

remove all but a specific portion of a string in javascript

I am writing a little app for Sharepoint. I am trying to extract some text from the middle of a field that is returned:
var ows_MetaInfo="1;#Subject:SW|NameOfADocument
vti_parservers:SR|23.0.0.6421
ContentTypeID:SW|0x0101001DB26Cf25E4F31488B7333256A77D2CA
vti_cachedtitle:SR|NameOfADocument
vti_title:SR|ATitleOfADocument
_Author:SW:|TheNameOfOurCompany
_Category:SW|
ContentType:SW|Document
vti_author::SR|mrwienerdog
_Comments:SW|This is very much the string I need extracted
vti_categories:VW|
vtiapprovallevel:SR|
vti_modifiedby:SR|mrwienerdog
vti_assignedto:SR|
Keywords:SW|Project Name
ContentType _Comments"
So......All I want returned is "This is very much the string I need extracted"
Do I need a regex and a string replace? How would you write the regex?
Yes, you can use a regular expression for this (this is the sort of thing they are good for). Assuming you always want the string after the pipe (|) on the line starting with "_Comments:SW|", here's how you can extract it:
var matchresult = ows_MetaInfo.match(/^_Comments:SW\|(.*)$/m);
var comment = (matchresult==null) ? "" : matchresult[1];
Note that the .match() method of the String object returns an array. The first (index 0) element will be the entire match (here, we the entire match is the whole line, as we anchored it with ^ and $; note that adding the "m" after the regex makes this a multiline regex, allowing us to match the start and end of any line within the multi-line input), and the rest of the array are the submatches that we capture using parenthesis. Above we've captured the part of the line that you want, so that will present in the second item in the array (index 1).
If there is no match ("_Comments:SW|" doesnt appear in ows_MetaInfo), then .match() will return null, which is why we test it before pulling out the comment.
If you need to adjust the regex for other scenarios, have a look at the Regex docs on Mozilla Dev Network: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
You can use this code:
var match = ows_MetaInfo.match(/_Comments:SW\|([^\n]+)/);
if (match)
document.writeln(match[1]);
I'm far from competent with RegEx, so here is my RegEx-less solution. See comments for further detail.
var extractedText = ExtractText(ows_MetaInfo);
function ExtractText(arg) {
// Use the pipe delimiter to turn the string into an array
var aryValues = ows_MetaInfo.split("|");
// Find the portion of the array that contains "vti_categories:VW"
for (var i = 0; i < aryValues.length; i++) {
if (aryValues[i].search("vti_categories:VW") != -1)
return aryValues[i].replace("vti_categories:VW", "");
}
return null;
}​
Here's a working fiddle to demonstrate.

Categories