I have two strings that i would like to extract specific strings from.
var companyString1;
var companyName1;
var companyString2;
var companyName2;
var stockString1 = "STOCKDETAILS:TWEETS:FB:Facebook Inc.";
var stockString2 = "I have returned -- Facebook Inc. (FB) -- stock back.";
companySymbol1 = ? //would like this to be "FB"
companyName1 = ? //would like this to be "Facebook Inc."
companySymbol2 = ? //would like this to be "FB"
companyName2 = ? //would like this to be "Facebook Inc."
What is regex i can apply to stockSTring1 to extract "FB" (into companySymbol1 var) and "Facebook Inc." (into companyName1 var). Similarly i want to extract "FB" (into companySymbol2 var) and "Facebook Inc." (into companyName2 var) fro stockString2.
The format of stockString1, stockString2 will be guaranteed to be consistent fro source -- so you can assume there could be other symbols and names (e.g. GOOG/Google Inc, MSFT/Microsoft Corp. etc)
Truly appreciate any help.
You could do this with split, and one regular expression just to chop off the closing ) in the second case:
function getStock(s) {
var parts = s.split(/\)? -- /);
if (parts.length < 2) { // other format
return s.split(':').slice(2, 4);
}
return parts[1].split(' (').reverse();
}
var stockString1 = "STOCKDETAILS:TWEETS:FB:Facebook Inc.";
var stockString2 = "I have returned -- Facebook Inc. (FB) -- stock back.";
var [companySymbol1, companyName1] = getStock(stockString1);
var [companySymbol2, companyName2] = getStock(stockString2);
console.log(companySymbol1, companyName1);
console.log(companySymbol2, companyName2);
Related
I have a web page in which contents are loaded dynamically from json. Now i need to find the texts like so2,co2,h2o after the page gets loaded and have to apply subscript for those texts. Is it possible to do this?? If yes please let me know the more efficient way of achieving it.
for example :
var json = { chemA: "value of CO2 is", chemB: "value of H2O is" , chemC: "value in CTUe is"};
in the above json i need to change CO2,H2O and e in CTUe as subscript. how to achieve this??
Take a look at this JSfiddle which shows two approaches:
HTML-based using the <sub> tag
Pure Javascript-based by replacing the matched number with the subscript equivalent in unicode:
http://jsfiddle.net/7gzbjxz3/
var json = { chemA: "CO2", chemB: "H2O" };
var jsonTxt = JSON.stringify(json).replace(/(\d)+/g, function (x){
return String.fromCharCode(8320 + parseInt(x));
});
Option 2 has the advantage of being more portable since you're actually replacing the character. I.e., you can copy and paste the text into say notepad and still see the subscripts there.
The JSFiddle shows both approaches. Not sure why the magic number is 8320 when I was expecting it to be 2080...
So you are generating DOM element as per JSON data you are getting. So before displaying it to DOM you can check if that JSON data contains so2,co2,h2o and if it is then replace that with <sub> tag.
For ex:
var text = 'CO2';
text.replace(/(\d+)/g, "<sub>" + "$1" + "</sub>") ;
And this will returns something like this: "CO2".
As per JSON provided by you:
// Only working for integer right now
var json = { chemA: "value of CO2 is", chemB: "value of H2O is" , chemC: "value in CTUe is"};
$.each(json, function(index, value) {
json[index] = value.replace(/(\d+)/g, "<sub>" + "$1" + "</sub>");
});
console.log(json);
Hope this will helps!
To do this, I would create a prototype function extending String and name it .toSub(). Then, when you create your html from your json, call .toSub() on any value that might contain text that should be in subscript:
// here is the main function
String.prototype.toSub = function() {
var str=this;
var subs = [
['CO2','CO<sub>2</sub>'],
['H2O','H<sub>2O</sub>'],
['CTUe','CO<sub>e</sub>'] // add more here as needed.
];
for(var i=0;i<subs.length;i++){
var chk = subs[i][0];
var rep = subs[i][1];
var pattern = new RegExp('^'+chk+'([ .?!])|( )'+chk+'([ .?!])|( )'+chk+'[ .?!]?$','ig'); // makes a regex like this: /^CO2([ .?!])|( )CO2([ .?!])|( )CO2[ .?!]?$/gi using the surrent sub
// the "empty" capture groups above may seem pointless but they are not
// they allow you to capture the spaces easily so you dont have to deal with them some other way
rep = '$2$4'+rep+'$1$3'; // the $1 etc here are accessing the capture groups from the regex above
str = str.replace(pattern,rep);
}
return str;
};
// below is just for the demo
var json = { chemA: "value of CO2 is", chemB: "value of H2O is" , chemC: "value in CTUe is", chemD: "CO2 is awesome", chemE: "I like H2O!", chemF: "what is H2O?", chemG: "I have H2O. Do you?"};
$.each(json, function(k, v) {
$('#result').append('Key '+k+' = '+v.toSub()+'<br>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
Note:
Anytime you do something like this with regex, you run the chance of unintentionally matching and converting some unwanted bit of text. However, this approach will have far fewer edge cases than searching and replacing text in your whole document as it is much more targeted.
So I'm working on this project that involves translating a string of text such as "als;kdfja;lsjkdf" into regular charaters like "the big dog" by parsing for certain pairs of letters that translate. (i.e: "fj" = "D")
The catch is I cant simply use the .replace() function in javascript, because there are many occurences where it's given the text "fjkl", and needs to find "jk" and logically interprets the collision of "fj" and "kl" to say that it's found it. This wont work for me, because for me, it didnt find it, as i am only trying to look at found pairs within 2 characters at a time. (i.e: "fjkl" could only yeild "fj" and "kl".)
(In the end I intend to utilize just the 8 characters "asdfjkl;" and set pairs of characters to actual letters. (in this subsitution method, fyi, "fj" OR "jf" would actually be "_"(space). )
in trying to figure out this task in javascript, (I dont know if another language might handle it more efficiently,) I tried utilizing the "split" function in the following way. (Disclaimer, I'm not sure if this is formatted 100% perfectly)
<textarea id="textbox"></textarea>
<script>
var text = document.getElementById("textbox").value; //getting string from the textarea
var pairs = text.split(/(..)/).filter(String); //spliting string into pairs
if(pairs == "fj"){replace(pairs, " ")} //some sort of subsitution
</script>
Additionally, if possible, i would like the replaced characters to be fed directly into the textarea continuosly as the user types, so the translation happens almost simutaneously. (I'm assuming this will use some sort of setInterval() function?)
If any tips can be given on the correct formatting of which tools i should use in javascript, that would be very outstanding; Thanks in advance.
if your interested, here is full list of subsitutions im making in the end of this project:
syntax:(X OR Y == result)
AJ JA = F
AK KA = V
AL LA = B
A; ;A = Y
SJ JS = N
SK KS = M
SL LS = S
S; ;S = P
DJ JD = A
DK DK = U
DL LD = D
D; ;D = G
FJ JF = _
FK KF = I
FL LF = T
F; ;F = K
AS SA = C
SD DS = L
DF FD = E
JK KJ = O
KL LK = R
L; ;L = Z
AD DA = -
SF FS = ,
AF FA = .
JL LJ = !
K; ;K = :
J; ;J = ?
-Daniel Rehman
I have prepared a code for your requirement. You can bind a function on keydown to allow continuous changes as you type in the textarea.
I am using replacePair method to replace a pair of character by its equivalent uppercase representation. You can inject your own custom logic here.
var tb = document.getElementById('tb');
var processedLength = 0;
var pairEntered=false;
tb.onkeydown = function (e) {
pairEntered=!pairEntered;
if (pairEntered) {
var nextTwoChars = this.value.substr(this.value.length - 2, 2);
var prevPart=this.value.substr(0,this.value.length-2);
var finalText=prevPart+ replacePair(nextTwoChars);
this.value=finalText;
processedLength+=2;
}
}
function replacePair(str){
return str.toUpperCase();
}
jsfiddle:http://jsfiddle.net/218fq7t2/
updated fiddle as per your replacement logic: http://jsfiddle.net/218fq7t2/3/
If you can be assured that certain pairs always translate to the same character, then perhaps a dictionary object can help.
var dict = { as:"A", kl:"B", al:"C", fj:"D" ... };
And, if your 'decryption' algorithm is 'lazy' (evaluates the first pair it encounters), then you can just travel through the input string.
var outputString = "", c, cl;
for (c = 1, cl = inputString.length; c < cl; c += 2) {
outputString += dict[inputString[c-1] + inputString[c]] || "";
}
If your replacement algorithm is not any more complicated than simply looking up which letter the pair represents, then this should do alright for you. No real logic necessary.
Couldn't you do it as follows:
var text = document.getElementById("textbox").value;
for (i = 0; i <= text.length; i++) {
if (text[i] == "j") {
if (text[i+1] == "f") {
pair = "jf";
text = text.replace(pair, "_");
}
}
What this would do is it would always, when checking any letter, also check the letter after it during the same step in the procedure. When it finds both letter i and letter i+1 matching up with a pair you are looking for, then the letters will be replaced by a space (or whatever you want), meaning that when the for-loop reaches the next run after a pair was found, the size of the text string will have been reduced by one. Thus, when it increments i, it will automatically skip the letter that made up the second component of the found pair. Thus, "jfkl" will be identified as two different pairs and your algorithm will not be confused.
of course, you would also have to work in the other pairs/codewords into the for loop so that they are all checked in some way
I had hoped my previous answer was enough to get you started. I was merely providing an algorithm that you could then use to your liking (wrap it in a function and add your own event listeners, etc).
Here is the solution to your problem. I did not write the entire dictionary. You will need to complete that.
var dictionary = { "aj":"F", "ja":"F", "ak":"V", "ka":"V", "al":"B", "la":"B", "a;":"Y", ";a":"Y" }
var input, output;
function init() {
input = document.getElementById("input");
output = document.getElementById("output");
input.addEventListener("keyup", decrypt, false);
}
function decrypt () {
if (!input || !output) {
return;
}
var i = input.value, o = "", c, cl;
for (c = 1, cl = i.length; c < cl; c += 2) {
o += dictionary[ i[c-1] + i[c] ] || "";
}
while (output.hasChildNodes()) {
output.removeChild(output.firstChild);
}
output.appendChild(document.createTextNode(o));
}
window.addEventListener("load", init, false);
<textarea id="input"></textarea>
<div id="output"></div>
I am trying to Titlecase some text which contains corporate names and their stock symbols.
Example (these strings are concatenated as corporate name, which gets title cased and the symbol in parens): AT&T (T)
John Deere Inc. (DE)
These corporate names come from our database which draws them from a stock pricing service. I have it working EXCEPT for when the name is an abbreviation like AT&T
That is return, and you guessed it right, like At&t. How can I preserve casing in abbreviations. I thought to use indexof to get the position of any &'s and uppercase the two characters on either side of it but that seems hackish.
Along the lines of(pseudo code)
var indexPos = myString.indexOf("&");
var fixedString = myString.charAt(indexPos - 1).toUpperCase().charAt(indexPos + 1).toUpperCase()
Oops, forgot to include my titlecase function
function toTitleCase(str) {
return str.replace(/([^\W_]+[^\s-]*) */g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}
Any better suggestions?
A better title case function may be
function toTitleCase(str) {
return str.replace(
/(\b.)|(.)/g,
function ($0, $1, $2) {
return ($1 && $1.toUpperCase()) || $2.toLowerCase();
}
);
}
toTitleCase("foo bAR&bAz a.e.i."); // "Foo Bar&Baz A.E.I."
This will still transform AT&T to At&T, but there's no information in the way it's written to know what to do, so finally
// specific fixes
if (str === "At&T" ) str = "AT&T";
else if (str === "Iphone") str = "iPhone";
// etc
// or
var dict = {
"At&T": "AT&T",
"Iphone": "iPhone"
};
str = dict[str] || str;
Though of course if you can do it right when you enter the data in the first place it will save you a lot of trouble
This is a general solution for title case, without taking your extra requirements of "abbreviations" into account:
var fixedString = String(myString).toLowerCase().replace(/\b\w/g, String.toUpperCase);
Although I agree with other posters that it's better to start with the data in the correct format in the first place. Not all proper names conform to title case, with just a couple examples being "Werner von Braun" and "Ronald McDonald." There's really no algorithm you can program into a computer to handle the often arbitrary capitalization of proper names, just like you can't really program a computer to spell check proper names.
However, you can certainly program in some exception cases, although I'm still not sure that simply assuming that any word with an ampersand in it should be in all caps always appropriate either. But that can be accomplished like so:
var titleCase = String(myString).toLowerCase().replace(/\b\w/g, String.toUpperCase);
var fixedString = titleCase.replace(/\b\w*\&\w*\b/g, String.toUpperCase);
Note that your second example of "John Deere Inc. (DE)" still isn't handled properly, though. I suppose you could add some other logic to say, put anything word between parentheses in all caps, like so:
var titleCase = String(myString).toLowerCase().replace(/\b\w/g, String.toUpperCase);
var titleCaseCapAmps = titleCase.replace(/\b\w*\&\w*\b/g, String.toUpperCase);
var fixedString = titleCaseCapAmps.replace(/\(.*\)/g, String.toUpperCase);
Which will at least handle your two examples correctly.
How about this: Since the number of registered companies with the stock exchange is finite, and there's a well-defined mapping between stock symbols and company names, your best best is probably to program that mapping into your code, to look up the company name by the ticker abbreviation, something like this:
var TickerToName =
{
A: "Agilent Technologies",
AA: "Alcoa Inc.",
// etc., etc.
}
Then it's just a simple lookup to get the company name from the ticker symbol:
var symbol = "T";
var CompanyName = TickerToName[symbol] || "Unknown ticker symbol: " + symbol;
Of course, I would be very surprised if there was not already some kind of Web Service you could call to get back a company name from a stock ticker symbol, something like in this thread:
Stock ticker symbol lookup API
Or maybe there's some functionality like this in the stock pricing service you're using to get the data in the first place.
The last time I faced this situation, I decided that it was less trouble to simply include the few exceptions here and there as need.
var titleCaseFix = {
"At&t": "AT&T"
}
var fixit(str) {
foreach (var oldCase in titleCaseFix) {
var newCase = titleCaseFix[oldCase];
// Look here for various string replace options:
// http://stackoverflow.com/questions/542232/in-javascript-how-can-i-perform-a-global-replace-on-string-with-a-variable-insi
}
return str;
}
An example of what im trying to get:
String1 - 'string.co.uk' - would return 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'string` and 'co.uk'
I currently have this:
var split= [];
var tld_part = domain_name.split(".");
var sld_parts = domain_name.split(".")[0];
tld_part = tld_part.slice(1, tld_part.length);
split.push(sld_parts);
split.push(tld_part.join("."));
With my current code, it takes the split parameter from the beginning, i want to reverse it if possible. With my current code it does this:
String1 - 'string.co.uk' - returns 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'random` and 'words.string.co.uk'
Any suggestions?
To expand upon elclanrs comment:
function getParts(str) {
var temp = str.split('.').slice(-3) // grabs the last 3 elements
return {
tld_parts : [temp[1],temp[2]].join("."),
sld_parts : temp[0]
}
}
getParts("foo.bar.baz.co.uk") would return { tld_parts : "co.uk", sld_parts : "baz" }
and
getParts("i.got.99.terms.but.a.bit.aint.one.co.uk") would return { tld_parts : "co.uk", sld_parts : "one" }
try this
var str='string.co.uk'//or 'random.words.string.co.uk'
var part = str.split('.');
var result = part[part.length - 1].toString() + '.' + part[part.length - 1].toString();
alert(result);
One way that comes to mind is the following
var tld_part = domain_name.split(".");
var name = tld_part[tld_part.length - 2];
var tld = tld_part[tld_part.length - 1] +"."+ tld_part[tld_part.length];
Depending on your use case, peforming direct splits might not be a good idea — for example, how would the above code handle .com or even just localhost? In this respect I would go down the RegExp route:
function stripSubdomains( str ){
var regs; return (regs = /([^.]+)(\.co)?(\.[^.]+)$/i.exec( str ))
? regs[1] + (regs[2]||'') + regs[3]
: str
;
};
Before the Regular Expression Police attack reprimand me for not being specific enough, a disclaimer:
The above can be tightened as a check against domain names by rather than checking for ^., to check for the specific characters allowed in a domain at that point. However, my own personal perspective on matters like these is to be more open at the point of capture, and be tougher from a filtering point at a later date... This allows you to keep an eye on what people might be trying, because you can never be 100% certain your validation isn't blocking valid requests — unless you have an army of user testers at your disposal. At the end of the day, it all depends on where this code is being used, so the above is an illustrated example only.
CDATA-blocks work great for coding large blocks of HTML, or CSS, into strings. But, I can't figure out how to use a variable-value within one.
For example, consider this JavaScript code:
var FullName = "Friedrich Hayek";
var ProfileCode = (<><![CDATA[
<div id="BigHonkingChunkO_HTML">
...Lot's o' code...
Name: $FullName$
Birth: $Birthdate$
...Lot's o' code...
... $FullName$ ...
...Lot's o' code...
</div>
]]></>).toString ();
How do I get $FullName$ to render as "Friedrich Hayek" instead of "$FullName$"?
Note that there is more than one variable and each variable can be used a few times in the CDATA block.
Alternate code sample:
var UserColorPref = "red";
var UI_CSS = (<><![CDATA[
body {
color: $UserColorPref$;
}
]]></>).toString ();
Looking to set the color attribute to red.
Is it elegant enough ?
function replaceVars(content, vars)
{
return content.replace(/\$(\w+)\$/g, function($0, $1)
{
return ($1 in vars ? vars[$1] : $0);
});
}
ProfileCode = replaceVars(ProfileCode, {"FullName" : "Friedrich Hayek"});
In case associative keys don't really matter, you can always opt to use:
sprintf or vsprintf
EDIT
What about making the 2nd parameter optional ?
function replaceVars(content, scope) {
if (!scope || typeof scope != "object") {
scope = this;
}
return content.replace(/\$(\w+)\$/g, function($0, $1) {
return ($1 in scope ? scope[$1] : $0);
});
}
// example1
var FullName = "Friedrich Hayek";
ProfileCode = replaceVars(ProfileCode);
// example2
var vars = {"FullName" : "Friedrich Hayek"};
ProfileCode = replaceVars(ProfileCode, vars);
ProfileCode=ProfileCode.replace('$FullName$',FullName);
After scouring the CDATA spec, and this "CDATA Confusion" article, it seems that CDATA sections treat everything as pure text, except for character-data entities and the section end marker (]]>). For example,
var x = $('<!DOCTYPE X[<!ENTITY foo "BAR">]><z> cc A &foo;</z>');
console.log ($(x, 'z').text() );
Yields: ]> cc A &foo;
So, there's no way to have variable substitution within a CDATA section. The best we can do is start and stop the sections, like so:
var FullName = "Friedrich Hayek";
var ProfileCode = (<><![CDATA[
<div id="BigHonkingChunkO_HTML">
...Lot's o' code...
Name: ]]></>).toString () + FullName+ (<><![CDATA[
...Lot's o' code...
</div>
]]></>).toString ();
console.log (ProfileCode);
-- which is obviously not acceptable.
Practical workaround:
It won't help anyone looking for a CDATA solution (which we now know is impossible, per the spec). But as we were just using CDATA as a method to generate a complex string, then we can clean the string up afterwards, per Ratna Dinakar's answer.
The function we ended up using is:
function sSetVarValues (sSrcStr, sReplaceList /* , Variable */)
/*--- function sSetVarValues takes a string and substitutes marked
locations with the values of the variables represented.
Conceptually, sSetVarValues() operates a little like sprintf().
Parameters:
sSrcStr -- The source string to be replaced.
sReplaceList -- A string containing a comma-separated list of variable
names expected in the raw string. For example, if
sReplaceList was "Var_A", we would expect (but not require)
that sSrcStr contained one or more "$Var_A$" substrings.
*Variable* -- A variable-length set of parameters, containing the values
of the variables specified in sReplaceList. For example,
if sReplaceList was "Var_A, Var_B, Var_C", then there better
be 3 parameters after sReplaceList in the function call.
Returns: The replaced string.
*/
{
if (!sSrcStr) return null;
if (!sReplaceList) return null;
var aReplaceList = sReplaceList.split (/,\s?/);
for (var J = aReplaceList.length-1; J >= 0; --J)
{
var zRepVar = new RegExp ('\\$' + aReplaceList[J] + '\\$', "g");
sSrcStr = sSrcStr.replace (zRepVar, arguments[J+2]);
}
return sSrcStr;
}
Sample use:
var AAA = 'first';
var BBB = 'second';
var CCC = 'third';
var Before = "1 is $AAA$, 2 is $BBB$, 3 is $CCC$";
var After = sSetVarValues (Before, "AAA, BBB, CCC", AAA, BBB, CCC);
console.log (Before);
console.log (After);
Yields:
1 is $AAA$, 2 is $BBB$, 3 is $CCC$
1 is first, 2 is second, 3 is third