So what I'm trying to accomplish is that for example if I have 0000-0000-0000-0000, then I'd like to have for example 2nd code letters only and/or specific letters that I could set myself as a preset such as: 2KS8-LMAO-8XG2-48SY. Right now I have the code to replace each string with random letter/number that I've written in html.
function randomised(len) {
return Math.floor(Math.random() * len);
}
function randomiseString(str){
var charSet = "abcdefghijklmnopqrstuvwxyz0123456789";
var str = str.replace(/[^-]/g,function() {
var a = charSet[randomised(charSet.length)].toUpperCase();
return a;
});
return str;
}
$('.combination').text(function(i,t){
return randomiseString(t);
});
--
<b>Random Combination:</b> <span class="combination">0000-0000-0000-0000</span>
Thanks in advance.
You would need to somehow pass in a pattern that you wanted it to match. Then separate your str_replace into multiple parts. So, if you wanted to replace a character you would use one set of characters, with a letter you would use a different set of characters. Something like this perhaps:
var chars = "abcdefghijklmnopqrstuvwxyz"
var nums = "0123456789"
str.replace(/[0-9]/g, function () {
return nums[randomised(nums.length()];
}
str.replace(/[a-z]/g, function () {
return chars[randomised(chars.length()].toUpperCase();
}
In this case, whatever str holds will be the pattern, you could then define patterns. Such as 0000-aaaa-0000-aaaa each time you run the script, the pattern will remain the same (i.e. 4 numbers, 4 letters, etc)
Related
I've got a string of text which can have specific tags in it.
Example: var string = '<pause 4>This is a line of text.</pause><pause 7>This is the next part of the text.</pause>';
What I'm trying to do is do a regex match against the <pause #></pause> tag.
For each tags found, in this case it's <pause 4></pause> and <pause 7></pause>. What I want is to grab the value 4 and 7, and the string length divided by for the string in between the <pause #>...</pause> tags.
What I have for now is not much.
But I cant figure out how to grab all the cases, then loop through each one and grab the values I'm looking for.
My function for this looks like this for now, it's not much:
/**
* checkTags(string)
* Just check for tags, and add them
* to the proper arrays for drawing later on
* #return string
*/
function checkTags(string) {
// Regular expresions we will use
var regex = {
pause: /<pause (.*?)>(.*?)<\/pause>/g
}
var matchedPauses = string.match(regex.pause);
// For each match
// Grab the pause seconds <pause SECONDS>
// Grab the length of the string divided by 2 "string.length/2" between the <pause></pause> tags
// Push the values to "pauses" [seconds, string.length/2]
// Remove the tags from the original string variable
return string;
}
If anyone can explain my how I could do this I would be very thankful! :)
match(/.../g) doesn't save subgroups, you're going to need exec or replace to do that. Here's an example of a replace-based helper function to get all matches:
function matchAll(re, str) {
var matches = [];
str.replace(re, function() {
matches.push([...arguments]);
});
return matches;
}
var string = '<pause 4>This is a line of text.</pause><pause 7>This is the next part of the text.</pause>';
var re = /<pause (\d+)>(.+?)<\/pause>/g;
console.log(matchAll(re, string))
Since you're removing tags anyways, you can also use replace directly.
You need to make a loop to find all matched groups of your RegExp pattern in the text.
The matched group is an array containing the original text, the matched value and the match text.
var str = '<pause 4>This is a line of text.</pause><pause 7>This is the next part of the text.</pause>';
function checkTags(str) {
// Regular expresions we will use
var regex = {
pause: /<pause (.*?)>(.*?)\<\/pause>/g
}
var matches = [];
while(matchedPauses = regex.pause.exec(str)) {
matches.push([matchedPauses[1], matchedPauses[2].length /2]);
};
return matches;
}
console.log(checkTags(str));
As a start point since you have not much so far you could try this one
/<pause [0-9]+>.*<\/pause>/g
Than to get the number out there you match again using
/[0-9]+>/g
To get rid of the last sign >
str = str.slice(0, -1);
I'm writing a function but cannot figure out how to account for upper case letter and punctuation.
My function is :
function countWords(word, string) {
var subStr = string.split(word);
return subStr.length - 1;
}
And it works when I try to test is with wordCount("hey","this is code hey"), but not if I try ("HEY", "this is code hey")
I tried
var subStr= string.toUpperCase().split(word)
but it will not work with lower case letters anymore.
Why can't you try like this.
function countWords(word, string) {
word= word.toLowerCase();
string=string.toLowerCase();
var subStr = string.split(word);
return subStr.length - 1;
}
So that whatever values we sent it will be converted into lower case then it will split.
Does it makes sense right?
Try this :
function countWords(word, string) {
var subStr = string.toLowerCase().split(word.toLowerCase());
return subStr.length - 1;
}
$(document).ready(function(){
$('#result').html(countWords("HEY","this is code hey"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result"></div>
Try sending the parameter to either all upper or lower cases first so that it matches the case of the string you are comparing it to. For example,
function countWords(word.toLowerCase, string.toLowerCase)
That way the search is evaluated regardless of case.
You could use a regex with the i and g modifier (case insensitive/match all) and match, then return the length:
function wordCount(search, txt) {
var regex = new RegExp("\\W" + search + "\\W|\\W" + search, "ig");
var match = txt.match(regex);
return match ? match.length : 0;
}
console.log(wordCount("hey","this is code heyHey HEY hey")); // 2
If you want to have heyHey as 2 matches, simply remove |\\W" + search from the regex
As a follow up to this question (not by me), I need to replace leading numbers of an id with \\3n (where n is the number we're replacing).
Some examples:
"1foo" -> "\\31foo"
"1foo1" -> "\\31foo1"
"12foo" -> "\\31\\32foo"
"12fo3o4" -> "\\31\\32fo3o4"
"foo123" -> "foo123"
Below is a solution that replaces every instance of the number, but I don't know enough regex to make it stop once it hits a non-number.
function magic (str) {
return str.replace(/([0-9])/g, "\\3$1");
}
... Or is regex a bad way to go? I guess it would be easy enough to do it, just looping over each character of the string manually.
Here is a way to achieve what you need using a reverse string + look-ahead approach:
function revStr(str) {
return str.split('').reverse().join('');
}
var s = "12fo3o4";
document.write(revStr(revStr(s).replace(/\d(?=\d*$)/g, function (m) {
return m + "3\\\\";
}))
);
The regex is matching a number that can be followed by 0 or more numbers only until the end (which is actually start) of a reversed string (with \d(?=\d*$)). The callback allows to manipulate the match (we just add reversed \\ and 3. Then, we just reverse the result.
Just use two steps: first find the prefix, then operate on its characters:
s.replace(/^\d+/, function (m) {
return [].map.call(m, function (c) {
return '\\3' + c;
}).join('');
});
No need to emulate any features.
Here is how I would have done it:
function replace(str) {
var re = /^([\d]*)/;
var match = str.match(re)[0];
var replaced = match.replace(/([\d])/g, "\\3$1");
str = str.replace(match, replaced);
return str;
}
document.write(replace("12fo3o4"));
Don't get me wrong: the other answers are fine! My focus was more on readability.
I've two variables:
var input = "user1#gmail.com";
var preferredPatterns = ["*#gmail.com", "*#yahoo.com", "*#live.com"];
Want to match the input with preferred pattern array. If any of the patterns matches I've to do certain task (in this example, input is a definite match). How can I match against an array of pattern in javascript?
You can compile your patterns (if they are valid regular expressions) into one for performance:
var masterPattern = new RegExp(patterns.join('|'));
Putting it all together:
var input = 'user1#gmail.com';
var preferredPatterns = [
".*#gmail.com$",
".*#yahoo.com$",
".*#live.com$"
];
var masterPattern = new RegExp(preferredPatterns.join('|'));
console.log(masterPattern.test(input));
// true
You need to use RegExp constructor while passing a variable as regex.
var input = 'user1#gmail.com';
var preferredPatterns = [".*#gmail\\.com$", ".*#yahoo\\.com$", ".*#live\\.com$"];
for (i=0; i < preferredPatterns.length;i++) {
if(input.match(RegExp(preferredPatterns[i]))) {
console.log(preferredPatterns[i])
}
}
Dot is a special meta-character in regex which matches any character. You need to escape the dot in the regex to match a literal dot.
As #zerkms said, you could use the below list of patterns also.
var preferredPatterns = ["#gmail\\.com$", "#yahoo\\.com$", "#live\\.com$"];
Try this helper function:
/**
* Returns an integer representing the number of items in the patterns
* array that contain the target string text
*/
function check(str, patterns) {
return patterns.reduce(function (previous, current) {
return previous + (str.indexOf(current) == -1 ? 0 : 1);
}, 0);
}
check("user#gmail.com", ["#gmail.com", "#yahoo.com", "#live.com"]; // returns 1
check("user#live.com", ["#gmail.com", "#yahoo.com", "#live.com"]; // returns 0
If you want a general approach to matching against a list of regular expressions then some version of Avinash Raj's answer will work.
Based on the fact that you are specifying certain domains, you might want to match any valid email address using the regex here, and if it matches then check if the domain is a preferred one. There are a number of different ways you could do that of course. Here's just a simple example, splitting on the # and using jQuery.inArray() to check if the domain is preferred.
var preferredDomains = ["gmail.com", "yahoo.com", "live.com"];
function isValid(inputVal) {
var re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(inputVal) && $.inArray(inputVal.split('#')[1], preferredDomains) > -1;
}
The advantage here is that the underlying regex doesn't change, just the much easier to read/maintain list of domains. You could tweak this to capture the domain in a group, instead of using split().
No regexp you may do as follows;
function matchPattern(xs, [y,...ys]){
function helper([x,...xs]){
return "*" + xs.join('') === y ? true
: xs.length ? helper(xs)
: false;
}
return helper(xs) ? y
: ys.length ? matchPattern(xs,ys)
: "No Match..!";
}
var input = "user1#gmail.com",
preferredPatterns = ["*#yahoo.com", "*#live.com", "*#gmail.com"];
result = matchPattern(input, preferredPatterns);
console.log(result);
preferredPatterns.forEach(function(element, index){
if(input.match('/'+element) != null){
console.log('matching ' + element)
}
})
you can write your custom logic if a string matches any pattern.
You may iterate through array and then use regex to compare with individual items.
I'm trying to replicate CI's humanize() and underscore() function in Javascript.
From the CI documentation, underscore() takes multiple words separated by spaces and underscores them while humanize() takes multiple words separated by underscores and adds spaces between them. The CI implementation looks something like:
function underscore($str) {
return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
}
function humanize($str) {
return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));
}
My code doesn't have to replicate the behavior exactly, but for the underscore() function I'd like it to be able to deal with multiple whitespace characters, while the humanize() function can be a bit looser and assume that only one underscore will only be there to separate each word.
So far what I have is:
function underscore(string) {
string = $.trim(string).toLowerCase();
var oldString;
while(oldString !== string){
oldString = string;
string = string.replace(/\s+/, '_');
}
return string;
}
function humanize(string) {
string = $.trim(string);
var terms = string.split('_');
for(var i=0; i < terms.length; i++){
terms[i] = terms[i].charAt(0).toUpperCase() + terms[i].slice(1);
}
return terms.join(' ');
}
Which works fine, yes, but I don't really like the way I did this (It's way too long compared to the PHP. There must be a more compact version), so I'm wondering if there's a more efficient / readable method to achieve this.
You can use the g modifier to do the replacement globally as:
function underscore(string) {
string = $.trim(string).toLowerCase();
return string.replace(/\s+/g, '_');
}