Extract string using regex in stored procedure - regex

I have a regex expression in javascript which works fine.
var re = /^([0-9]?[A-Z]+?)\s*(?:FM)?[FGHJKMNQUVXZ](?:[02]0)?[12]?[0-9]/i;
var str = 'RVBM2016';
var m;
if ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
Now I am trying to reuse the same expression in my stored procedure in postgres. Here is how I am trying it:
select regexp_replace('BLM2016',
E'/^([0-9]?[A-Z]+?)\s*(?:FM)?[FGHJKMNQUVXZ](?:[02]0)?[12]?[0-9]/i', '', 'g')
This should return BL only. For RVBM2016 it should return RVB and so on..
But now it has no effect on the input text. Is there any syntactical mistake?

I was using the wrong method to extract string out of expression. The correct version is as follows if anyone is interested:
select (regexp_matches('BLM2016', '([0-9]?[A-Z]+?)\s*(?:FM)?[FGHJKMNQUVXZ](?:[02]0)?[12]?[0-9]', 'gi'))[1]

Related

Typescript regex exclude whole string if followed by specific string

I'm been running into weird issues with regex and Typescript in which I'm trying to have my expression replace the value of test minus the first instance if followed by test. In other words, replace the first two lines that have test but for the third line below, replace only the second value of test.
[test]
[test].[db]
[test].[test]
Where it should look like:
[newvalue]
[newvalue].[db]
[test].[newvalue]
I've come up with lots of variations but this is the one that I thought was simple enough to solve it and regex101 can confirm this works:
\[(\w+)\](?!\.\[test\])
But when using Typescript (custom task in VSTS build), it actually replaces the values like this:
[newvalue]
[newvalue].[db]
[newvalue].[test]
Update: It looks like a regex like (test)(?!.test) breaks when changing the use cases removing the square brackets, which makes me think this might be somewhere in the code. Could the problem be with the index that the value is replaced at?
Some of the code in Typescript that is calling this:
var filePattern = tl.getInput("filePattern", true);
var tokenRegex = tl.getInput("tokenRegex", true);
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.info(`Starting regex replacement in [${file}]`);
var contents = fs.readFileSync(file).toString();
var reg = new RegExp(tokenRegex, "g");
// loop through each match
var match: RegExpExecArray;
// keep a separate var for the contents so that the regex index doesn't get messed up
// by replacing items underneath it
var newContents = contents;
while((match = reg.exec(contents)) !== null) {
var vName = match[1];
// find the variable value in the environment
var vValue = tl.getVariable(vName);
if (typeof vValue === 'undefined') {
tl.warning(`Token [${vName}] does not have an environment value`);
} else {
newContents = newContents.replace(match[0], vValue);
console.info(`Replaced token [${vName }]`);
}
}
}
Full code is for the task I'm using this with: https://github.com/colindembovsky/cols-agent-tasks/blob/master/Tasks/ReplaceTokens/replaceTokens.ts
For me this regex is working like you are expecting:
\[(test)\](?!\.\[test\])
with a Typescript code like that
myString.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
Instead, the regex you are using should replace also the [db] part.
I've tried with this code:
class Greeter {
myString1: string;
myString2: string;
myString3: string;
greeting: string;
constructor(str1: string, str2: string, str3: string) {
this.myString1 = str1.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.myString2 = str2.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.myString3 = str3.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.greeting = this.myString1 + "\n" + this.myString2 + "\n" + this.myString3;
}
greet() {
return "Hello, these are your replacements:\n" + this.greeting;
}
}
let greeter = new Greeter("[test]", "[test].[db]", "[test].[test]");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(greeter.greet());
}
document.body.appendChild(button);
Online playground here.

Reuse a captured group outside of the regex string

I'm reading from a text file that has many lines containing placeholders like this: "{name_of_placeholder}". There is another file that's like a map - the keys are the names of each placeholder and there's a value for each one. I would like to use regex to find every placeholder in the first file and replace {name_of_placeholder} with the corresponding value from the second file.
The first thing that came to my mind is to capture the group between "{}", but how to use it outside of the string? If that's not possible maybe someone can think of another way to do this?
Thanks in advance!
Although you haven't defined the language, but whatever the language is, you can try the following approach:
var dict={}
const regex1 = /(.*)=(.*)/gm;
// let str1 be the second file (dictionary)
const str1 = `abc1=1
abc2=2
abc3=3
abc4=4
abc5=5
abc6=6
abc7=7
abc8=8
abc9=9
abc10=10
abc11=11
abc12=12`;
let m1;
while ((m1 = regex1.exec(str1)) !== null) {
if (m1.index === regex1.lastIndex) {
regex1.lastIndex++;
}
dict[m1[1]]=m1[2];
}
//console.log(dict);
const regex = /\{(.*?)\}/gm;
// let str be the first file where you want the replace operation on {key...}
var str = `adfas{abc1} asfasdf
asdf {abc3} asdfasdf
asdfas {abc5} asdfasdf
asdfas{abc7} asdfasdfadf
piq asdfj asdf
`;
let m;
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
str=str.replace("\{"+m[1]+"\}",dict[m[1]]);
}
console.log(str);

regex search term in variable

Do you know how I am able to put the search string inside the RegExp?
Let say if my search term is 'Ame', then I can write
v.name.search(new RegExp(/Ame/i)). //It works
var search = $("#search-query").val();
v.name.search(new RegExp('/'+search+'/i' //It doesn't work
However if the value 'Ame' was stored in the var 'search', how do I use the var?
var search = $("#search-query").val();
if($("#search-query").val().length <1){
$scope.hiddenError = true;
return;
}
$.each(json.products, function(i, v) {
if (v.name.search(new RegExp('/'+search+'/i')) != -1) { //doesn't work
$scope.recentGame.push({ label:v.name, value: v.type, link: v.url });
return;
}
});
When you want to build a custom regular expression from a string, you don't include the delimiters / or the options. You use the following form of the function constructor:
var regex = new RegExp(search, "i");
and use that in the search method.

What is the equalient of JavaScript's "s.replace(/[^\w]+/g, '-')" in Dart language?

I am trying to get the following working code in JavaScript also working in Dart.
https://jsfiddle.net/8xyxy8jp/1/
var s = "We live, on the # planet earth";
var results = s.replace(/[^\w]+/g, '-');
document.getElementById("output").innerHTML = results;
Which gives the output
We-live-on-the-planet-earth
I have tried this Dart code
void main() {
print( "We live, on the # planet earth".replaceAll("[^\w]+","-"));
}
But the output becomes the same.
What am I missing here?
If you want replaceAll() to process the argument as regular expression you need to pass a RegExp instance. I usually use r as prefix for the regex string to make it a raw string where not interpolation ($, \, ...) takes place.
main() {
var s = "We live, on the # planet earth";
var result = s.replaceAll(new RegExp(r'[^\w]+'), '-');
print(result);
}
Try it in DartPad

AS3 RegEx returns null

Can anyone explain why the code below traces null when on the timeline?
var cleanRegExp:RegExp = /^[a-zA-Z0-9]+(\b|\/)/;
var str:String = "/num83r5/and/letters/4/A/";
trace(str.match(cleanRegExp.toString()));
I've read the documentation, so I'm pretty sure that I'm declaring the RegEx correctly and that String.match() should only return null when no pattern is passed in, otherwise it should be an array with 0+ elements. I suspected a badly written expression, but surely that should still return an empty array?
EDIT: Both these trace "no matches" instead of either 5 or 0, depending on the expression being correct:
var cleanRegExp:RegExp = /^[a-zA-Z0-9]+(\b|\/)/;
var str:String = "/num83r5/and/letters/4/A/";
var res:Array = str.match(cleanRegExp);
trace((res == null) ? "no matches" : res.length);
And:
var cleanRegExp:RegExp = /^[a-zA-Z0-9]+(\b|\/)/;
var str:String = "/num83r5/and/letters/4/A/";
var res:Object = cleanRegExp.exec(str);
trace((res == null) ? "no matches" : res[0]);
UPDATE
If you're going to work in flash with regex, this tool is a must-have:
http://gskinner.com/RegExr/
http://gskinner.com/RegExr/desktop/
ORIGINAL ANSWER
Don't use toString(), you're then doing a literal search, which will include the addition of all of your regex formatting, including flags. Do:
str.match(cleanRegExp);
In fact the proper method is to reference the returned object like so:
var results:Array = str.match(cleanRegExp);
if(results != null){
//We have a match!
}