I have a function which autocompletes a username when they start typing with # (kind of like instagram)
When you type an # a list of users appears and the user can click on an item/user "ex: #User1" in the list and the script autocompletes the # with the username in the textarea "ex: #User1".
The first replacement goes wel "ex: #User1". But when the user types the second # (and not a first letter yet) and the list appears again and then clicks on a different item/user in the list, the chosen item/user "ex: #User2" gets added within the first # in front of the first suggestion "ex: #User2User1". But on the otherhand if the user types the second # WITH a first letter and THEN clicks on the item/user in the list the replacement goes well.
Link to codepen sample
this is my current function :
var string = $scope.searchParam;
var pattern = /#\b.+?\b/g;
$scope.match = string.match(pattern)
if($scope.match){
value = $scope.match.pop();
console.log('match')
}else{
console.log('was undefined');
var pattern = /#/g;
var found = string.match(pattern)
console.log(found +' is value');
if(found.length > 0){
value = found.pop();
}
}
string = string.replace(value, '#'+suggestion);
console.log('oke');
$scope.searchParam = string;
$scope.searchFilter = string;
i also tried to check if it was present allready to only trigger when a character is typed after the #sign with this:
if(watching && typeof $scope.searchParam !== 'undefined' && $scope.searchParam !== null) {
var string = $scope.searchParam;
var pattern = /#\b.+?\b/g;
$scope.match = string.match(pattern)
if($scope.match){
console.log($scope.match.length + 'match aantal' + $scope.i + ' i aantal');
$scope.matches.push($scope.match);
console.log($scope.matches);
var found = $filter('filter')($scope.matches,$scope.match,true)
if (!found.length) {
$scope.i++;
}
}
$scope.completing = true;
$scope.searchFilter = $scope.searchParam;
$scope.selectedIndex = -1;
}
but the matches are only a couple of letters so this array get's flooded. there are probably multiple answers to this problem and i'd like to know what you would go with in this situation.
The problem is in this line:
string = string.replace(value, '#'+suggestion);
If you only type # it will replace the first #. To avoid that, you have to match the last one:
string = string.replace(new RegExp(value+'$'), '#'+suggestion);
This will match the value only if it's at the end of the string, which is what you need.
You can check it on codepen.
Related
I'm trying to manipulate a string that has tested as a positive match against my regex statement.
My regex statement is /\[table=\d](.*?)\[\/table] / gmi and an example of a positive match would be [table=1]Cell 1[c]Cell 2[/table]. I'm searching for matches within a certain div, which I'll call .foo in the code below.
However, once the search comes back saying it has found a match, I want to have the section that was identified as a match returned back to me so that I can start manipulating a specific section of it, namely count the number of times [c] appears and reference the number in [table=1].
(function(regexCheck) {
var regex = /\[table=\d](.*?)\[\/table] / gmi;
$('.foo').each(function() {
var html = $(this).html();
var change = false;
while (regex[0].test(html)) {
change = true;
//Somehow return string?
}
});
})(jQuery);
I'm quite new to javascript and especially new to RegEx, so I apologise if this code is crude.
Thanks for all of your help in advance.
Use exec instead of test and keep the resulting match object:
var match;
while ((match = regex[0].exec(html)) != null) {
change = true;
// use `match[0]` for the full match, or `match[1]` and onward for capture groups
}
Simple example (since your snippet isn't runnable, I've just created a simple one instead):
var str = "test 1 test 2 test 3";
var regex = /test (\d)/g;
var match;
while ((match = regex.exec(str)) !== null) {
console.log("match = " + JSON.stringify(match));
}
I need to split a a university course code into prefix and suffix. e.g. CSE1011 into Prefix CSE and Suffix 1011 . Prefix may be 2 or more Alphabets and suffix may be none/ 3 or more. So far I have come up with this RegEx:
/([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var splitted = courseRegex.exec(courscrCode);
console.log(splitted);
Also tried This. I am getting more match
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
if (courscrCode.match(courseRegex)) {
var splitted = courscrCode.split(courseRegex);
console.log(splitted.length);
if (splitted.length > 1) {
splitted.forEach(function(value, index) {
if ((value != '') && (value != undefined))
console.log(value, index);
});
}
} else {
console.log('course code mangled');
}
I need a solution where i am going to get exactly 2 sub-string prefix and suffix. now I am getting more that 2. I am also open to any other solution
As Terry noted above, MDN states that the array returned by regex will always include the matched text as the first item. The code below will remove the first element.
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var splitted = courseRegex.exec(courscrCode);
splitted.splice(0,1);
console.log(splitted);
Your splitted array in SECOND sample code is:
["", "CSE", "1011", ""]
If your input text courscrCode is always one course code, you should find prefix in [1] and number in [2]
If input text may be more than just course code to validate, some changes are required.
Note: first empty item in array is all characters before CSE and last item in array is all characters after 1011. It's not whole matched value
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var prefix = '' ;
var suffix = '' ;
if (courscrCode.match(courseRegex)) {
var splitted = courscrCode.split(courseRegex);
console.log(splitted.length);
if (splitted.length > 1) {
prefix = splitted[1];
suffix = splitted[2];
//or:
splitted.splice(0,1);
splitted.splice(2,1);
console.log(splitted);
}
} else {
console.log('course code mangled');
}
I have javascript code that will validate alphanumeric and dashes for any field it is assigned to. The regex completes successfully and the error message displays. What I would like to happen is upon hitting a key that would make the regex true it would delete the variable that set it to true (for example if someone where to hit the # key it would only delete the # character). Right now I have it set to erase the entire field.
function validateAlphaNumericField(field) {
var value = field.value;
var reg = /[^A-Za-z0-9-]/;
var newVal = reg.test(value)
if (newVal == true) {
alert("This field must contain only alphanumeric and dashes.");
field.value="";
}
}
you can replace the unexpected characters as following:
var value = field.value;
var reg = /[^A-Za-z0-9-]/;
return value.replace(reg,'');
I want to remove special characters from the starting of the string only.
i.e, if my string is like {abc#xyz.com then I want to remove the { from the starting. The string shoould look like abc#xyz.com
But if my string is like abc{#xyz.com then I want to retain the same string as it is ie., abc{#xyz.com.
Also I want to check that if my string has # symbol present or not. If it is present then OK else show a message.
The following demonstrates what you specified (or it's close):
var pat = /^[^a-z0-9]*([a-z0-9].*?#.*?$)/i; //pattern for optional non-alphabetic start followed by alphabetic, followed by '#' somewhere
var testString = "{abc#xyz.com"; //Try with {abcxyz.com for alert
arr = pat.exec(testString);
var adjustedString;
if (arr != null) { adjustedString = arr[1]; } //The potentially adjustedString (chopped off non-alphabetic start) will be in capture group 1
else { adjustedString = ""; alert(testString + " does not conform to pattern"); }
adjustedString;
I have used two separate regex objects to achieve what you require .It checks for both the conditions in the string.I know its not very efficient but it will serve your purpose.
var regex = new RegExp(/(^{)/);
var regex1 = new RegExp(/(^[^#]*$)/);
var str = "abc#gmail.com";
if(!regex1.test(str)){
if(regex.test(str))
alert("Bracket found at the beginning")
else
alert("Bracket not found at the beginning")
}
else{
alert("doesnt contain #");
}
Hope this helps
I have written a little JQuery / Javascript add on for our form, that takes a single full name input and breaks it into first and last name components. It opens a modal if there are three or more names in the input and asks which combo is correct.
My next step is finding and stripping any suffix that may have been entered such as Jr, Sr, III, etc. I am currently stripping off the last four characters and checking them with indexOf to see if they contain a suffix string (Jr, Sr, III, etc). But each line checks only one possible suffix and I am wondering is there is some js magic that will check multiple suffixs in one line. My current code is below:
var nameVal = $('#name').val();
var suffix = nameVal.slice(-4);
if (suffix.toLowerCase().indexOf(" jr") != -1) {
var nameSplit = nameVal.slice(0, -3).split(" ");
} elseif (suffix.toLowerCase().indexOf(" iii") != -1) {
var nameSplit = nameVal.slice(0, -4).split(" ");
} else {
var nameSplit = nameVal.split(" "); }
I can always do the good old || and keep adding extra (suffix.toLowerCase().indexOf(" jr") != -1) with a different indexOf value, but I am hoping to keep the code more compact if possible, my "little" script is already 3k.
Once I get this sorted the last step will be figuring out how to retain the last name value, so that further down the form when other names are entered and the script is called again it can check to see if the selected last name matches the new entry and bypass the modal pop up.
You can use a regular expression. Try something like this;
nameVal = nameVal.replace(/ (jr|sr|I?II)$/gi, "");
In more detail;
(jr|sr|I?II) = jr or sr or II or III
$ = at the end of line
/i = case insensitive
/g match globally
Probably best to use regexps for this, for example:
var names = [
"Joe Jr.",
"Mark Sr.",
"Loui III",
"Mark Lockering",
];
var suffixRes = [
/Jr\.$/, /Sr\.$/, 'III',
];
$(names).each(function(i, name) {
var str = name;
$(suffixRes).each(function(j, suffixRe) {
str = str.replace(suffixRe, '');
});
console.log(str);
});
Live example:
http://jsfiddle.net/am7QD/
In this case I usually make an array of values, (because I'm not good with regex)
var suffixArr = [' jr',' iii', ' ii'];
//then run a loop
for(var i = 0; i < suffixArr.length;i++){
if(suffixArr[i].toLowerCase().indexOf(suffixArr[i]) != -1){
nameSplit = nameVal.slice(0, - suffixArr[i].length).split(" ");
}
}