3 While Loops into a Single Loop? - javascript

I have to remove the commas, periods, and hyphens from an HTML text value. I do not want to write all 3 of these while loops, instead I only want one loop (any) to do all of this.
I already tried a while with multiple && and if else nested inside but i would always only just get the commas removed.
while(beg.indexOf(',') > -1)
{
beg = beg.replace(',','');
document.twocities.begins.value= beg;
}
while(beg.indexOf('-') > -1)
{
beg = beg.replace('-','');
document.twocities.begins.value= beg;
}
while(beg.indexOf('.') > -1)
{
beg= beg.replace('.','');
document.twocities.begins.value= beg;
}

You can do all this without loops by using regex.
Here is an example of removing all those characters using a single regex:
let str = "abc,d-e.fg,hij,1-2,34.56.7890"
str = str.replace(/[,.-]/g, "")
console.log(str)

No loops are necessary for this in the first place.
You can replace characters in a string with String.replace() and you can determine which characters and patterns to replace using regular expressions.
let sampleString = "This, is. a - test - - of, the, code. ";
console.log(sampleString.replace(/[,-.]/g, ""));

A single call to the replace function and using a regular expression suffice:
document.twocities.begins.value = beg = beg.replace(/[,.-]/g, "");
Regular expressions are a pattern matching language. The pattern employed here basically says "every occurrence of one of the characters ., ,, -)". Note that the slash / delimits the pattern while the suffix consists of flags controlling the matching process - in this case it is g (global) telling the engine to replace each occurrence ( as opposed to the first only without the flag ).
This site provides lots of info about regular expressions, their use in programming and implementations in different programming environments.
There are several online sites to test actual regular expression and what they match (including explanations), eg. Regex 101.
Even more details ... ;): You may use the .replace function with a string as the first argument (as you did in your code sample). However, only the first occurrence of the string searched for will be replaced - thus you would have to resort to loops. Specs of the .replace function (and of JS in general) can be found here.

Use regex like below.
let example = "This- is a,,., string.,";
console.log(example.replace(/[-.,]+/g, ""));

Related

regex encapsulation

I've got a question concerning regex.
I was wondering how one could replace an encapsulated text, something like {key:23} to something like <span class="highlightable">23</span, so that the entity will still remain encapsulated, but with something else.
I will do this in JS, but the regex is what is important, I have been searching for a while, probably searching for the wrong terms, I should probably learn more about regex, generally.
In any case, is there someone who knows how to perform this operation with simplicity?
Thanks!
It's important that you find {key:23} in your text first, and then replace it with your wanted syntax, this way you avoid replacing {key:'sometext'} with that syntax which is unwanted.
var str = "some random text {key:23} some random text {key:name}";
var n = str.replace(/\{key:[\d]+\}/gi, function myFunction(x){return x.replace(/\{key:/,'<span>').replace(/\}/, '</span>');});
this way only {key:AnyNumber} gets replaced, and {key:AnyThingOtherThanNumbers} don't get touched.
It seems you are new to regex. You need to learn more about character classes and capturing groups and backreferences.
The regex is somewhat basic in your case if you do not need any nested encapsulated text support.
Let's start:
The beginning is {key: - it will match the substring literally. Note that { can be a special character (denoting start of a limiting quantifier), thus, it is a good idea to escape it: {key:.
([^}]+) - This is a bit more interesting: the round brackets around are a capturing group that let us later back-reference the matched text. The [^}]+ means 1 or more characters (due to +) other than } (as [^}] is a negated character class where ^ means not)
} matches a } literally.
In the replacement string, we'll get the captured text using a backreference $1.
So, the entire regex will look like:
{key:([^}]+)}
See demo on regex101.com
Code snippet:
var re = /{key:([^}]+)}/g;
var str = '{key:23}';
var subst = '<span class="highlightable">$1</span>';
document.getElementById("res").innerHTML = str.replace(re, subst);
.highlightable
{
color: red;
}
<div id="res"/>
If you want to use a different behavior based on the value of key, then you'll need to adjust the regex to either match digits only (with \d+) or letters only (say, with [a-zA-Z] for English), or other shorthand classes, ranges (= character classes), or their combinations.
If your string is in var a, then:
var test = a.replace( /\{key:(\d+)\}/g, "<span class='highlightable'>$1</span>");

Regex for checking presence and absence of keywords in User Agent String

I'm using a Regex in Javascript to sniff the User Agent string. Here is some pseudo code below:
is_not_tablet_bool = /android.+mobile/i.test(navigator.userAgent.toLowerCase());
switch(true)
{
case (is_not_tablet_bool):
return true;
break;
}
I'm trying to craft a regex that will do something close to the opposite of the above i.e.
ensure that 'android' keyword is present in string, and at the same time
ensure that 'mobile' keyword is absent from string
Thanks for the anticipated assistance.
Negative lookahead
Regular expressions have a construct called negative lookahead which matches a string in the regular expression without capturing the lookahead part:
Your regular expression should be written this way:
/android(?!.*mobile)/i
This will match any string that contains word android that is not followed by word mobile with ignored case. This also means that you can remove the toLowerCase call.
Addition: Negative lookbehind
In case you need only match those strings that have word android in them but lack mobile (either before or after) then a combination of negative lookaheads and lookbehinds will do.
/(?<!mobile.*)android(?!.*mobile)/i
But the problem is that Javascript doesn't support negative lookbehinds. So you have to employ a different trick that will help you determining that situation.
There are several possibilities of which following seem to be most interesting (and last one useful):
Replace a matching negative string that will fail afterwards:
var nav = navigator.userAgent.replace(/mobile.*android/, "fail" );
return /android(?!.*mobile)/i.test(nav);
Use two lookaheads. One on normal string and the other on reversed one while also having a reversed regular expression:
var nav = navigator.userAgent;
var after = /android(?!.*mobile)/i.test(nav);
var before = /diordna(?!.*elibom)/i.test(nav.split("").reverse().join(""));
return before && after;
Simplicity is key. Two simple regular expressions would do the trick just fine as well:
var nav = navigator.userAgent;
return /android/i.test(nav) && !/mobile/i.test(nav);
Note: I'm not sure whether your code is actual code, because if it is I would strongly recommend you reconsider the use of switch(true) statement and simply replace it by
return is_not_tablet_bool;.
I don't think using regular expressions makes this task any easier. I would simply check for the inclusion and exclusion of those strings using the String.indexOf(...) method:
function isNotAndroidMobile(userAgentString) {
var ua = userAgentString.toLowerCase();
return (ua.indexOf('android')>=0) && (ua.indexOf('mobile')===-1);
}

JavaScript RegEx Match Failing

I am having issues matching a string using regex in javascript. I am trying to get everything up to the word "at". I am using the following and while it doesn't return any errors, it also doesn't do anything either.
var str = "Team A at Team B";
var matches = str.match(/(.*?)(?=at|$)/);
I tried multiple regex patterns before coming across this SO post, Regex to capture everything before first optional string, but it doesn't to return what I want.
Remove the ? at your first capturing group, and |$ from your second, and add ^ to mark beginning of string:
str.match(/^(.*)(?=at)/)
Alternatively (I personally find below easier to read, but your call):
str.substr(0, str.search(/\bat\b/))

How to make this simple regexp?

I need to make a string starts and ends with alphanumeric range between 5 to 20 characters and it could have a space or none between characters. /^[a-z\s?A-Z0-9]{5,20}$/ but this is not working.
EDIT
test test -should pass
testtest -should pass
test test test -should not pass
You can't do this with traditional regex without writing a ridiculously long expression, so you need to use a look-ahead:
/^(?=(\w| ){15,20}$)\w+ ?\w+$/
This says, make sure there are between 15 and 20 characters in the match, then match /\w+ \w+/
Note I used \w for simplification. It is the same as your character class above except it also accepts underscores. If you don't want to match them you have to do:
/^(?=[a-zA-Z0-9 ]{15,20}$)[a-zA-Z0-9]+ ?[a-zA-Z0-9]+$/
You can't put a ? inside of [...]. [...] is used to specify a set of characters precisely, you can't maybe (?) have a character inside a set of characters. The occurrence of any specific characters is already optional, the ? is meaningless.
If you allow any number of spaces inside your match, just remove the question mark. If you want to allow a single space but no more, then regular expressions alone can't do that for you, you'd need something like
if (myString.match(/^[a-z\sA-Z0-9]{5,20}$/ && myString.match(/\s/g).length <= 1)
You couldn't do this with a single traditional regex without it being dozens of lines long; regexes are meant for matching more simpler patterns than this.
If you only want to use regexes, you could use two instead of one. The first matches the general pattern, the second ensures that only one non-space characters is found.
if (myString.match(/^[a-z\sA-Z0-9]{5,20}$/ && myString.match(/^[^\s]*\s?[^\s]*$/))) {
Example Usage
inputs = ["test test", "testtest", "test test test"];
for (index in inputs) {
var myString = inputs[index];
if (myString.match(/^[a-z\sA-Z0-9]{5,20}$/ && myString.match(/^[^\s]*\s?[^\s]*$/))) {
console.log(myString + " matches.")
} else {
console.log(myString + " does not match.")
}
}
This produces the output specified in your question.
Meh , So here's the ridiculously long traditional regex for the same
(?i)[a-z0-9]+( [a-z0-9]+)?{5,12}
js vesrion (w/o the nested quantifier)
/^([a-z0-9]( [a-z0-9])?){5,12}$/i

Split string in JavaScript using a regular expression

I'm trying to write a regex for use in javascript.
var script = "function onclick() {loadArea('areaog_og_group_og_consumedservice', '\x26roleOrd\x3d1');}";
var match = new RegExp("'[^']*(\\.[^']*)*'").exec(script);
I would like split to contain two elements:
match[0] == "'areaog_og_group_og_consumedservice'";
match[1] == "'\x26roleOrd\x3d1'";
This regex matches correctly when testing it at gskinner.com/RegExr/ but it does not work in my Javascript. This issue can be replicated by testing ir here http://www.regextester.com/.
I need the solution to work with Internet Explorer 6 and above.
Can any regex guru's help?
Judging by your regex, it looks like you're trying to match a single-quoted string that may contain escaped quotes. The correct form of that regex is:
'[^'\\]*(?:\\.[^'\\]*)*'
(If you don't need to allow for escaped quotes, /'[^']*'/ is all you need.) You also have to set the g flag if you want to get both strings. Here's the regex in its regex-literal form:
/'[^'\\]*(?:\\.[^'\\]*)*'/g
If you use the RegExp constructor instead of a regex literal, you have to double-escape the backslashes: once for the string literal and once for the regex. You also have to pass the flags (g, i, m) as a separate parameter:
var rgx = new RegExp("'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'", "g");
while (result = rgx.exec(script))
print(result[0]);
The regex you're looking for is .*?('[^']*')\s*,\s*('[^']*'). The catch here is that, as usual, match[0] is the entire matched text (this is very normal) so it's not particularly useful to you. match[1] and match[2] are the two matches you're looking for.
var script = "function onclick() {loadArea('areaog_og_group_og_consumedservice', '\x26roleOrd\x3d1');}";
var parameters = /.*?('[^']*')\s*,\s*('[^']*')/.exec(script);
alert("you've done: loadArea("+parameters[1]+", "+parameters[2]+");");
The only issue I have with this is that it's somewhat inflexible. You might want to spend a little time to match function calls with 2 or 3 parameters?
EDIT
In response to you're request, here is the regex to match 1,2,3,...,n parameters. If you notice, I used a non-capturing group (the (?: ) part) to find many instances of the comma followed by the second parameter.
/.*?('[^']*')(?:\s*,\s*('[^']*'))*/
Maybe this:
'([^']*)'\s*,\s*'([^']*)'

Categories