CodeMirror electricInput does not match expression with leading whitespace - regex

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;
}
}
});

Related

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

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

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.

Obfuscate email?

Let's start by saying I have a very large project, part of this project is to grab a user recovery action status, and a user email, and send it through a service layer back to the front end of the application. The catch is, the email needs to be altered on the back end so it doesn't get sent plain text. What I mean by this is, when the value gets populated on the back end, I need to have some code to modify it so it will have a format like this: j*****e#domain.com. This absolutely needs to be done in the method that I'm working on(which honestly isn't very big). Here is the method I have that will grab the status from another method within the same class, as well as grabbing the email of the user:
public CredentialRecoveryResponse RecoveryResponse(CredentialRecoveryRequest request)
{
CredentialRecoveryResponse response = new CredentialRecoveryResponse();
response.Status = RecoverCredentials(request);
if (response.Status == UserRecoveryActionStatus.Success)
{
User usr = UserRepository.GetByID(request.UserID);
response.Email = usr.EmailAddress;
}
return response;
}
Somehow, inside this method, I need to take that usr.EmailAddress and modify it do "block" or change the values to "*" for all characters except the first and last characters before the "#domain.com" portion. Is there a quick and easy way to do this within the method that way the whole email address isn't getting sent back through the wire?
Here's one take:
private static string ObfuscateEmail(string email)
{
return Regex.Replace(email, "^(?<name>[^#]+)", m => {
string match = m.Groups["name"].Value;
return match[0] + new String('*', match.Length - 1);
});
}
What is this doing?
The method uses Regex.Replace and passes a lambda function to do the actual replacement
The regex pattern simply says match everything to the left of the # sign and create a named group called 'name'.
The lambda function then takes the first character of the match and appends to it a series of asterisks, using an overload of the String method (char, int) which repeats that char N number of times. It's N-1 here since the first char is unobfuscated.

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]

Rails 3: validate REGEX fails if no value input

I am using the following REGEX
VALID_WEBSITE_REGEX = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$/ix
to validate a website entry with this rule:
validates :website, length: { maximum: 150 }, format: { with: VALID_WEBSITE_REGEX }
(The 150 is arbitrary).
However, when I save / update the form I get a validation error "website is invalid". How do I ensure that the 'format' section of the validation rule is processed only if there is content to process?
You can use allow_blank option for validation
:allow_blank => true
This option will let validation pass if the attribute’s value is blank?, like nil or an empty string for example.
read more:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#allow_blank
Enclose the entire thing with the ? operator, e.g.
VALID_WEBSITE_REGEX = /^((http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?)?$/ix
If you want to allow whitespace too, then add \s* on each end, e.g.
VALID_WEBSITE_REGEX = /^\s*((http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?)?\s*$/ix