javascript get string before a character - javascript

I have a string that and I am trying to extract the characters before the quote.
Example is extract the 14 from 14' - €14.99
I am using the follwing code to acheive this.
$menuItem.text().match(/[^']*/)[0]
My problem is that if the string is something like €0.88 I wish to get an empty string returned. However I get back the full string of €0.88.
What I am I doing wrong with the match?

This is the what you should use to split:
string.slice(0, string.indexOf("'"));
And then to handle your non existant value edge case:
function split(str) {
var i = str.indexOf("'");
if(i > 0)
return str.slice(0, i);
else
return "";
}
Demo on JsFiddle

Nobody seems to have presented what seems to me as the safest and most obvious option that covers each of the cases the OP asked about so I thought I'd offer this:
function getCharsBefore(str, chr) {
var index = str.indexOf(chr);
if (index != -1) {
return(str.substring(0, index));
}
return("");
}

try this
str.substring(0,str.indexOf("'"));

Here is an underscore mixin in coffescript
_.mixin
substrBefore : ->
[char, str] = arguments
return "" unless char?
fn = (s)-> s.substr(0,s.indexOf(char)+1)
return fn(str) if str?
fn
or if you prefer raw javascript : http://jsfiddle.net/snrobot/XsuQd/
You can use this to build a partial like:
var beforeQuote = _.substrBefore("'");
var hasQuote = beforeQuote("14' - €0.88"); // hasQuote = "14'"
var noQoute = beforeQuote("14 €0.88"); // noQuote = ""
Or just call it directly with your string
var beforeQuote = _.substrBefore("'", "14' - €0.88"); // beforeQuote = "14'"
I purposely chose to leave the search character in the results to match its complement mixin substrAfter (here is a demo: http://jsfiddle.net/snrobot/SEAZr/ ). The later mixin was written as a utility to parse url queries. In some cases I am just using location.search which returns a string with the leading ?.

I use "split":
let string = "one-two-three";
let um = string.split('-')[0];
let dois = string.split('-')[1];
let tres = string.split('-')[2];
document.write(tres) //three

Related

Get array of elements from a string and look up values

I have a calculation string from a database like:
var calc = "{a}+{b}==2"
and I want to pull all the elements with "{}" so that I can look up their values from a database. What's the fastest way of doing this, so I end up with an ordered array that I can look up, and replace the values back in the string.
I've considered:
- For loop, looking for { then finding the next }
- Split with a map
- IndexOf
Using regex
var exp = /{([^}]+)}/g ,index;
while(index = exp.exec("{a}+{b}==2")) {
console.log(index[1]);
}
.
Demo
Not sure if it's the "fastest" way, but you should consider using a regex.
Something like:
var calc = "{a}+{b}==2";
var re = /{([^}]+)}/g;
var res;
var result = [];
while (res = re.exec(calc))
{
result.push(res[1]);
}
console.log(result);
Your regex may need to be refined based on the actual definition of the {} expressions (based on allowed characters, quoting, etc.).
Once you have received the values back, you can then use replace to replace the values.
var values = {a: 1, b: 3};
var replaced = calc.replace(re,function(match,name) { return values[name]; });
console.log(replaced);
NB: be very careful if you plan to then send this to eval or the like.
Regex comes to the mind first but one other way of implementing this job in O(n) time could be;
function getDatas(s){
var dataOn = false;
return Array.prototype.reduce.call(s,(d,c) => dataOn ? c !== "}" ? (d[d.length-1] += c,d)
: (dataOn = false, d)
: c === "{" ? (dataOn = true, d.push(""),d)
: d, []);
}
var calc = "{a}+{b}+{colorSpace}==2",
result = getDatas(calc);
console.log(result);
So out of curiosity i have done some tests on JSBen and it seems that #jcaron's regex is indeed much efficient. You may extend those tests with any of your other ideas like indexOf or for loop.

regex to find specific strings in javascript

disclaimer - absolutely new to regexes....
I have a string like this:
subject=something||x-access-token=something
For this I need to extract two values. Subject and x-access-token.
As a starting point, I wanted to collect two strings: subject= and x-access-token=. For this here is what I did:
/[a-z,-]+=/g.exec(mystring)
It returns only one element subject=. I expected both of them. Where i am doing wrong?
The g modifier does not affect exec, because exec only returns the first match by specification. What you want is the match method:
mystring.match(/[a-z,-]+=/g)
No regex necessary. Write a tiny parser, it's easy.
function parseValues(str) {
var result = {};
str.split("||").forEach(function (item) {
var parts = item.split("=");
result[ parts[0] /* key */ ] = parts[1]; /* value */
});
return result;
}
usage
var obj = parseValues("subject=something||x-access-token=something-else");
// -> {subject: "something", x-access-token: "something-else"}
var subj = obj.subject;
// -> "something"
var token = obj["x-access-token"];
// -> "something-else"
Additional complications my arise when there is an escaping schema involved that allows you to have || inside a value, or when a value can contain an =.
You will hit these complications with regex approach as well, but with a parser-based approach they will be much easier to solve.
You have to execute exec twice to get 2 extracted strings.
According to MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
If your regular expression uses the "g" flag, you can use the exec() method multiple times to find successive matches in the same string.
Usually, people extract all strings matching the pattern one by one with a while loop. Please execute following code in browser console to see how it works.
var regex = /[a-z,-]+=/g;
var string = "subject=something||x-access-token=something";
while(matched = regex.exec(string)) console.log(matched);
You can convert the string into a valid JSON string, then parse it to retrieve an object containing the expected data.
var str = 'subject=something||x-access-token=something';
var obj = JSON.parse('{"' + str.replace(/=/g, '":"').replace(/\|\|/g, '","') + '"}');
console.log(obj);
I don't think you need regexp here, just use the javascript builtin function "split".
var s = "subject=something1||x-access-token=something2";
var r = s.split('||'); // r now is an array: ["subject=something1", "x-access-token=something2"]
var i;
for(i=0; i<r.length; i++){
// for each array's item, split again
r[i] = r[i].split('=');
}
At the end you have a matrix like the following:
y x 0 1
0 subject something1
1 x-access-token something2
And you can access the elements using x and y:
"subject" == r[0][0]
"x-access-token" == r[1][0]
"something2" == r[1][1]
If you really want to do it with a pure regexp:
var input = 'subject=something1||x-access-token=something2'
var m = /subject=(.*)\|\|x-access-token=(.*)/.exec(input)
var subject = m[1]
var xAccessToken = m[2]
console.log(subject);
console.log(xAccessToken);
However, it would probably be cleaner to split it instead:
console.log('subject=something||x-access-token=something'
.split(/\|\|/)
.map(function(a) {
a = a.split(/=/);
return { key: a[0], val: a[1] }
}));

Javascript regex to replace "split"

I would like to use Javascript Regex instead of split.
Here is the example string:
var str = "123:foo";
The current method calls:
str.split(":")[1]
This will return "foo", but it raises an Error when given a bad string that doesn't have a :.
So this would raise an error:
var str = "fooblah";
In the case of "fooblah" I'd like to just return an empty string.
This should be pretty simple, but went looking for it, and couldn't figure it out. Thank you in advance.
Remove the part up to and including the colon (or the end of the string, if there's no colon):
"123:foo".replace(/.*?(:|$)/, '') // "foo"
"foobar" .replace(/.*?(:|$)/, '') // ""
How this regexp works:
.* Grab everything
? non-greedily
( until we come to
: a colon
| or
$ the end of the string
)
A regex won't help you. Your error likely arises from trying to use undefined later. Instead, check the length of the split first.
var arr = str.split(':');
if (arr.length < 2) {
// Do something to handle a bad string
} else {
var match = arr[1];
...
}
Here's what I've always used, with different variations; this is just a simple version of it:
function split(str, d) {
var op = "";
if(str.indexOf(d) > 0) {
op = str.split(d);
}
return(op);
}
Fairly simple, either returns an array or an empty string.
var str1 = "123:foo", str2 = "fooblah";
var res = function (s) {
return /:/.test(s) && s.replace(/.*(?=:):/, "") || ""
};
console.log(res(str1), res(str2))
Here is a solution using a single regex, with the part you want in the capturing group:
^[^:]*:([^:]+)

Javascript to extract *.com

I am looking for a javascript function/regex to extract *.com from a URI... (to be done on client side)
It should work for the following cases:
siphone.com = siphone.com
qwr.siphone.com = siphone.com
www.qwr.siphone.com = siphone.com
qw.rock.siphone.com = siphone.com
<http://www.qwr.siphone.com> = siphone.com
Much appreciated!
Edit: Sorry, I missed a case:
http://www.qwr.siphone.com/default.htm = siphone.com
I guess this regex should work for a few cases:
/[\w]+\.(com|ca|org|net)/
I'm not good with JavaScript, but there should be a library for splitting URIs out there, right?
According to that link, here's a "strict" regex:
/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/
As you can see, you're better off just using the "library". :)
This should do it. I added a few cases for some nonmatches.
var cases = [
"siphone.com",
"qwr.siphone.com",
"www.qwr.siphone.com",
"qw.rock.siphone.com",
"<http://www.qwr.siphone.com>",
"hamstar.corm",
"cheese.net",
"bro.at.me.come",
"http://www.qwr.siphone.com/default.htm"];
var grabCom = function(str) {
var result = str.match("(\\w+\\.com)\\W?|$");
if(result !== null)
return result[1];
return null;
};
for(var i = 0; i < cases.length; i++) {
console.log(grabCom(cases[i]));
}
var myStrings = [
'siphone.com',
'qwr.siphone.com',
'www.qwr.siphone.com',
'qw.rock.siphone.com',
'<http://www.qwr.siphone.com>'
];
for (var i = 0; i < myStrings.length; i++) {
document.write( myStrings[i] + '=' + myStrings[i].match(/[\w]+\.(com)/gi) + '<br><br>');
}
I've placed given demo strings to the myStrings array.
i - is index to iterate through this array. The following line does the matching trick:
myStrings[i].match(/[\w]+\.(com)/gi)
and returns the value of siphone.com. If you'd like to match .net and etc. - add (com|net|other) instead of just (com).
Also you may find the following link useful: Regular expressions Cheat Sheet
update: missed case works too %)
You could split the string then search for the .com string like so
var url = 'music.google.com'
var parts = url.split('.');
for(part in parts) {
if(part == 'com') {
return true;
}
{
uri = "foo.bar.baz.com"
uri.split(".").slice(-2).join(".") // returns baz.com
This assumes that you want just the hostname and tld. It also assumes that there is no path information either.
Updated now that you also need to handle uris with paths you could do:
uri.split(".").slice(-2).join(".").split("/")[0]
Use regexp to do that. This way modifications to the detections are quite easy.
var url = 'www.siphone.com';
var domain = url.match(/[^.]\.com/i)[0];
If you use url.match(/(([^.]+)\.com)[^a-z]/i)[1] instead. You can assure that the ".com" is not followed by any other characters.

JavaScript indexOf to ignore Case

I am trying to find if an image has in its source name noPic which can be in upper or lower case.
var noPic = largeSrc.indexOf("nopic");
Should I write :
var noPic = largeSrc.toLowerCase().indexOf("nopic");
But this solution doesn't work...
You can use regex with a case-insensitive modifier - admittedly not necessarily as fast as indexOf.
var noPic = largeSrc.search(/nopic/i);
No, there is no case-insensitive way to call that function. Perhaps the reason your second example doesn't work is because you are missing a call to the text() function.
Try this:
var search = "nopic";
var noPic = largeSrc.text().toLowerCase().indexOf(search.toLowerCase());
Note that if the search string is from user input you'll need to escape the special regexp characters.
Here's what it would look like:
var search = getUserInput();
/* case-insensitive search takes around 2 times more than simple indexOf() */
var regex = RegExp(search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "i");
var noPic = testString.search(regex);
See the updated jsperf: http://jsperf.com/regex-vs-tolowercase-then-regex/4
footnote: regexp escaping from https://stackoverflow.com/a/3561711/1333402
Try with:
var lowerCaseLargeSrc = largeSrc.toLowerCase();
var noPic = lowerCaseLargeSrc.indexOf("nopic");
Your code will only work if largeSrc is already a string. You might be getting an input that's an html element instead. So, use jQuery to resolve any potential input element into the text that's inside it. Example:
var noPic = largeSrc.text().toLowerCase().indexOf("nopic");
How about using findIndex instead that way you can do all your toLowerCase() inside the callback. Worked great for me:
// Not Supported in IE 6-11
const arr = ['HELLO', 'WORLD'];
const str = 'world';
const index = arr.findIndex(element => {
return element.toLowerCase() === str.toLowerCase();
});
console.log(index); // 👉️ 1
if (index !== -1) {
// 👉️ string is in the array
}
Credit:
https://bobbyhadz.com/blog/javascript-make-array-indexof-case-insensitive

Categories

Resources