Grunt: replace wildcard value when using grunt-text-replace - regex

I'm no regex master, and I'm pretty sure a regex is what is needed in this instance.
I currently have a text replacement task like so:
configSeed: {
src: ['src/*/local/app-config.js'],
overwrite: true,
replacements: [
{
from: 'var CONFIG_SEED_STRING = null;',
to: 'var CONFIG_SEED_STRING = "{"some_stringified_dynamic_json":"values"}";'
}
]
}
Which works fine the first time the config file is saved, the above string is replaced.
However, as soon as the string is replaced, further changes to the config don't have a replacement applied because obviously null is no longer to be found.
null is where my wildcard value needs to be, and the value could be either null (initially) or subsequent replacing a valid JSON string instead.
If my assumption about a wildcard being needed is true, would that trigger recursion upon save? Or does Grunt have in-built protection against this situation? [edit: I've tested this by replacing the string with the same value, recursion does not occur.]
So, assuming it is safe to use a wildcard where I want to, could I please get help with a regex value to be replaced?
Alternative solutions also welcome, for example my code base is unchanging enough that I could viably replace a line of code completely, if that's possible.
Thanks for any help provided.

Omg, I actually did it, what a feeling. After some painful reading on regex again:
configSeed: {
src: ['src/*/local/app.js'],
overwrite: true,
replacements: [
{
from: /var CONFIG_SEED_STRING = '[^']*'/g,
to: 'var CONFIG_SEED_STRING = \'{"foo":"bar"}\''
},
{
from: 'var CONFIG_SEED_STRING = null',
to: 'var CONFIG_SEED_STRING = \'{"foo":"bar"}\''
}
]
}
Not perfect, because I have two from/tos, but it catches both null and valid JSON data in between single quoted String value for CONFIG_SEED_STRING.
Instant reward time for writing a regex! I'm allowing myself 15 minutes of Youtube at work.

Related

Extract JSON from String using flutter dart

Hello I want to extract JSON from below input string.
I have tried bellow regex in java and it is working fine,
private static final Pattern shortcode_media = Pattern.compile("\"shortcode_media\":(\\{.+\\})");
I want in regex for dart.
Input String
<script type="text/javascript">window.__initialDataLoaded(window._sharedData);</script><script type="text/javascript">window.__additionalDataLoaded('/p/B9fphP5gBeG/',{"graphql":{"shortcode_media":{"__typename":"GraphSidecar","id":"2260708142683789190","shortcode":"B9fphP5gBeG","dimensions":{"height":1326,"width":1080}}}});</script><script type="text/javascript">
<script type="text/javascript">window.__initialDataLoaded(window._newData);</script><script type="text/javascript">window._newData('/p/B9fphP5gBeG/',{"graphql":{"post":{"__typename":"id","id":"2260708142683789190","new_code":"B9fphP5gBeG"}}});</script><script type="text/javascript">
(function(){
function normalizeError(err) {
var errorInfo = err.error || {};
var getConfigProp = function(propName, defaultValueIfNotTruthy) {
var propValue = window._sharedData && window._sharedData[propName];
return propValue ? propValue : defaultValueIfNotTruthy;
};
return {}
}
)
Expected json
{"graphql":{"shortcode_media":{"__typename":"GraphSidecar","id":"2260708142683789190","shortcode":"B9fphP5gBeG","dimensions":{"height":1326,"width":1080}}}}
Note: There are multiple json string in input string, i need json of shortcode_media tag
please use
void main() {
​
String json = '''
{"graphql":
{"shortcode_media":{"__typename":"GraphSidecar","id":"2260708142683789190","shortcode":"B9fphP5gBeG","dimensions":{"height":1326,"width":1080}}},
"abc":{"def":"test"}
}
''';
RegExp regExp = new RegExp(
"\"shortcode_media\":(\\{.+\\})",
caseSensitive: false,
multiLine: false,
);
print(regExp.stringMatch(json).toString());
}
output
"shortcode_media":{"__typename":"GraphSidecar","id":"2260708142683789190","shortcode":"B9fphP5gBeG","dimensions":{"height":1326,"width":1080}}}
Dartpad
The corresponding Dart RegExp would be:
static final RegExp shortcodeMedia = RegExp(r'"shortcode_media":(\{.+\})");
It does not work, though. JSON is not a regular language, so you can't parse it using regular expressions.
The value of "shortcode_media" in your example JSON ends with several } characters. The RegExp will stop the match at the third of those, even though the second } is the one matching the leading {. If your JSON text contains any further values after the shortcode_media entry, those might be included as well.
Stopping at the first } would also be too short.
If someone reorders the JSON source code to the equivalent
"shortcode_media":{"dimensions":{"height":1326,"width":1080},"__typename":"GraphSidecar","id":"2260708142683789190","shortcode":"B9fphP5gBeG"}
(that is, putting the "dimensions" entry first), then you would only capture until the end of the dimensions block.
I would recommend either using a proper JSON parser, or at least improving the RegExp to be able to handle a single nested JSON object - since you seem to already know that it will happen.
Such a RegExp could be:
RegExp(r'"shortcode_media":(\{(?:[^{}]*(?:\{.*?\})?)*?\})')
This RegExp will capture the correct number of braces for the example code, but still won't work if there are more nested JSON objects. Only a real parser can handle the general case correctly.

Regex in JSX file not working, trying to remove the quotation marks "" that return around name

const Json = ({ data }: any) => <pre>{JSON.stringify(data, null, 4)}</pre>;
let profileName = <Json data={account.name.replace(/\"/g, '')}/>
not used to using regex, but I am trying to remove all instances of ""
When I use that regex with a normal hardcoded string of a name it works, why doesn't it work with this one?
what'up?
The JSON.stringify() automatically put quotes!
Remove it!
I hope to help!

Custom vallidator to ban a specific wordlist

I need a custom validator to ban a specific list of banned words from a textarea field.
I need exactly this type of implementation, I know that it's not logically correct to let the user type part of a query but it's exactly what I need.
I tried with a regExp but it has a strange behaviour.
My RegExp
/(drop|update|truncate|delete|;|alter|insert)+./gi
my Validator
export function forbiddenWordsValidator(sqlRe: RegExp): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const forbidden = sqlRe.test(control.value);
return forbidden ? { forbiddenSql: { value: control.value } } : null;
};
}
my formControl:
whereCondition: new FormControl("", [
Validators.required,
forbiddenWordsValidator(this.BAN_SQL_KEYWORDS)...
It works only in certain cases and I don't understand why does the same string works one time and doesn't work if i delete a char and rewrite it or sometimes if i type a whitespace the validator returns ok.
There are several issues here:
The global g modifier leads to unexpected alternated results when used in RegExp#test and similar methods that move the regex index after a valid match, it must be removed
. at the end requires any 1 char other than line break char, hence it must be removed.
Use
/drop|update|truncate|delete|;|alter|insert/i
Or, to match the words as whole words use
/\b(?:drop|update|truncate|delete|alter|insert)\b|;/i
This way, insert in insertion and drop in dropout won't get "caught" (=matched).
See the regex demo.
it's not a great idea to give such power to the user

CodeMirror electricInput does not match expression with leading whitespace

In my custom mode for CodeMirror, I want the electricInput event to fire when the user types a line starting with the word bank (with optional leading whitespace).
I have electricInput set up like this: electricInput: /\s*bank$/i
The event DOES fire when the user types bank at the beginning of a line. It does NOT fire when there are spaces before the word bank. Why?
(the RegEx seems to be fine. I have a grammar rule in that mode with the same RegEx, and it matches the token as expected, regardless of leading white spaces:
CodeMirror.defineSimpleMode("myMode", {
start: [
{regex: /\s*bank$/i, token: 'bank', sol: true, indent: true}
Thanks to Marijn's kind help on the CodeMirror discussions forum, I was able to solve this: a custom indent function needs to be passed to defineSimpleMode. Then, we still need to set electricInput (because otherwise the indent function does not get called when typing bank). But no event handler for onElectricInput is required.
CodeMirror.defineSimpleMode("myMode", {
start: [
...
],
meta: {
electricInput: /\s*bank$/i,
indent: function (state, textAfter, line) {
if (textAfter.substring(0, 4).toLowerCase() === 'bank') return 0
return 2;
}
}
});

How do I get the jquery validate plugin to only allow text, spaces, periods, and hyphens?

I'm using http://bassistance.de/jquery-plugins/jquery-plugin-validation/ to validate my form. Unfortunately, there is no text only method. So I tried to write my own:
$(document).ready(function(){
$("#staffedit").validate(
{
rules: {
editDisplayName: {
textonly: true,
required: true
}
}}
);
jQuery.validator.addMethod(
"textonly",
function(value, element)
{console.log('textonly called.');
console.log(/[-.\w\s]/.test(value));
return this.optional(element) || /[-.\w\s]/.test(value);
},
jQuery.format("Please only enter letters, spaces, periods, or hyphens.")
);
});
The method gets called, since my console.log function does output to the console at the appropriate times. What I don't understand, is why I can still put $ or * in the input field. I can put anything in there, and it still gets evaluated as valid.
I used http://regexpal.com/ to test the regex, and it works fine there.
So, how do I get the plugin to only allow text, spaces, periods, and hyphens?
On a side note, I'd also like to allow characters with accents, like à, É, ā, or ô...
The problem was with how the test() function works. It returns true if it makes any match. That's what had me so confused. The regex's I was using were actually doing what I thought they should. See http://www.w3schools.com/jsref/jsref_regexp_test.asp
/[^-\.a-zA-Z\s]/.test("David"); //Returns false
/[^-\.a-zA-Z\s]/.test("Davi$ *d"); //Returns true
//without the ^
/[-\.a-zA-Z\s]/.test("Davi$ *d"); //Returns true
/[-\.a-zA-Z\s]/.test("David"); //Returns true
As you can see, that's not very helpful. So what I did was pull the test out of the return statement. Like this:
$(document).ready(function(){
$("#staffedit").validate(
{
rules: {
editDisplayName: {
textonly: true,
required: true
}
}}
);
jQuery.validator.addMethod(
"textonly",
function(value, element)
{
valid = false;
check = /[^-\.a-zA-Z\s\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02AE]/.test(value);
if(check==false)
valid = true;
return this.optional(element) || valid;
},
jQuery.format("Please only enter letters, spaces, periods, or hyphens.")
);
});
So I check to see if any of the characters I don't want exist, if they don't test() returns false, so it's valid.
I also figured out the unicode stuff. [\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02AE] matches a bunch of stuff, I used http://en.wikipedia.org/wiki/List_of_Unicode_characters to figure out what to put in. I think I got everything I wanted. Thanks to Kyle Schmidt for posting the link to Javascript + Unicode regexes that helped me figure out the \u syntax. I should probably check the unicode a bit more thoroughly, but that should be enough for now.
Problem solved.
If you get the additional methods js there's a letters validator in there
http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/additional-methods.js
You want letterswithbasicpunc I believe
Putting the ^ inside a character class will negate what's in the character class. I'd go for [-.\w\s]