for reasons i can't go into too much details with here i have an id that could look like this:
1%20
The reason i have this is because im matching a table of alot of data.
1 means the table row 20 is the list it is in (from the database).
Now i have the following javascript code:
function getSplitId(id) {
return id.split('%');
}
Which works fine when i do the following:
selected_row_id = getSplitId($(this).get(0).id)[0];
Now i want to get the HTML id of the row ive clicked and for that i have the following code:
rowHtmlId = $(this).id;
Which also works fine however when i need to start using the rowHtmlId to something like for instance:
newElement = $('#' + rowHtmlId).prev();
I get the following error:
Syntax error, unrecognized expression: #44%24
So my question is how can i go around this?
If you have a look at the jQuery documentation, you see
To use any of the meta-characters ( such as !"#$%&'()*+,./:;<=>?#[\]^{|}~` ) as a literal part of a name, it must be escaped with with two backslashes: \\.
% is a meta character so you have to escape it first:
newElement = $('#' + rowHtmlId.replace('%', '\\%')).prev();
Or you simply use getElementById:
$(document.getElementById(rowHtmlId)).prev();
Or even better (depending on the context), just keep a reference to the row element itself:
var row = $(this);
// ... later
newElement = row.prev();
There is no need to query for it again if you already have a reference to it.
Just add a backslash to escape the percent sign:
id.split('\%');
in getSplitId() change from:
return id.split('%');
to
return id.split('\%');
Related
Say my string is this:
var testexample = <p nameIt="Title">Title_Test</p><figure class="t15"><table><thead><tr>
<th><span>Column1</span></th><th><span>Column2</span></th></tr></thead><tbody><tr><td><span>Entry1</span></td><td><span>Entry2</span></td><td><span>ready</span></td></tr></tbody></table></figure><p ex="ready">!aaa;
It's quite a long string, but it's a table written out in string form. How would I get the words from in between <span> and </span>? For example, I would like it to return Column1, Column2, Entry1, Entry2 (maybe in an array?)
Here is what I tried so far:
storing = testexample.match(/<span>(.*)</span>/);
But it only returned "Column1" I also tried doing matchAll, exec, and doing /<span>(.*)</span>/g. These results gave me the whole string, nothing, things like <th><span>Column1</span></th>, or the just "Column1" again.
I'm quite new at javascript so I'm unsure what I'm doing wrong as I have read the documentation for this. Any help would be appreciated. Thank you.
Your Regex should be using the global and multi flag -- But other than that you need to be checking for more than one instance .. Something like this:
<\s*span[^>]*>(.*?)<\s*\/\s*span\s*>
You can see it at work here:
Rexex 101
ALSO because as stated you can't reliably parse HTML with regex -- I did my best to make sure you could still use styles or attributes INSIDE the <span> tag .. IE <span style="color:#FF0000;"> will still work with the example I provided.
With another example here:
Regex 101
There is a very good answer of #bobince about why you should not even try to use regular expressions for parsing HTML
To help you with an answer you should provide info what environment you would like to use for such job.
Is it browser or node.js and do you have HTML as text or in a page?
I would propose another solution to your problem that creates dom elements that you will query to extract desired data.
/**
* Helper function to transform HTML string to dom element
* #param {string} html
* #param {string} elementType
* #returns {HTMLDivElement}
*/
function htmlToElement(html, elementType = 'div') {
const template = document.createElement(elementType);
template.innerHTML = html.trim(); // Never return a text node of whitespace as the result
return template;
}
const htmlString = `<p nameIt="Title">Title_Test</p><figure class="t15"><table><thead><tr>
<th><span>Column1</span></th><th><span>Column2</span></th></tr></thead><tbody><tr><td><span>Entry1</span></td><td><span>Entry2</span></td><td><span>ready</span></td></tr></tbody></table></figure><p ex="ready">`;
const element = htmlToElement(htmlString);
// extract inner text from spans as array of strings
const arrayOfWords = [...element.querySelectorAll('span')].map(span => span.innerText);
// convert array of strings to space separated string
const wordsJoinedWithSpace = arrayOfWords.join(' ');
// log a result in a console
console.log({arrayOfWords, wordsJoinedWithSpace});
As pointed out, you can't reliably parse random HTML with Regex. HOWEVER, assuming you only want to parse an HTML table of the kind you have in the question, this is your regex:
<span>(.*?)<\/span>
I changed a couple things:
You hadn't escaped the / in </span> so your regex was actually ended earlier
I added a ? in the match anything section. This way the regex will match the shortest possible sequence so you get to match all spans.
Calling match will match all occurences of this regex. This will also include the <span> / </span> parts
Trim the start and ending <span> parts
Here's the complete example:
var testexample = `<p nameIt="Title">Title_Test</p><figure class="t15"><table><thead><tr>
<th><span>Column1</span></th><th><span>Column2</span></th></tr></thead><tbody><tr><td><span>Entry1</span></td><td><span>Entry2</span></td><td><span>ready</span></td></tr></tbody></table></figure><p ex="ready">!aaa`;
var regex = /<span>(.*?)<\/span>/g;
var match = testexample.match(regex);
var columnContent = match.map(m => m.replace("<span>", "").replace("</span>", ""));
console.log(columnContent[0]); // Column1
console.log(columnContent[1]); // Column2
I want to find and replace text in a HTML document between, say inside the <title> tags. For example,
var str = "<html><head><title>Just a title</title></head><body>Do nothing</body></html>";
var newTitle = "Updated title information";
I tried using parseXML() in jQuery (example below), but it is not working:
var doc= $($.parseXML(str));
doc.find('title').text(newTitle);
str=doc.text();
Is there a different way to find and replace text inside HTML tags? Regex or may be using replaceWith() or something similar?
I did something similar in a question earlier today using regexes:
str = str.replace(/<title>[\s\S]*?<\/title>/, '<title>' + newTitle + '<\/title>');
That should find and replace it. [\s\S]*? means [any character including space and line breaks]any number of times, and the ? makes the asterisk "not greedy," so it will stop (more quickly) when it finds </title>.
You can also do something like this:
var doc = $($.parseXML(str));
doc.find('title').text(newTitle);
// get your new data back to a string
str = (new XMLSerializer()).serializeToString(doc[0]);
Here is a fiddle: http://jsfiddle.net/Z89dL/1/
This would be a wonderful time to use Javascript's stristr(haystack, needle, bool) method. First, you need to get the head of the document using $('head'), then get the contents using .innerHTML.
For the sake of the answer, let's store $('head').innerHTML in a var called head. First, let's get everything before the title with stristr(head, '<title>', true), and what's after the title with stristr(head, '</title>') and store them in vars called before and after, respectively. Now, the final line is simple:
head.innerHTML = before + "<title>" + newTitle + after;
I create an in memory div:
var video_div = document.createElement('div');
video_div.className = "vidinfo-inline";
In essence I have some variables:
var key = "data-video-srcs";
var value = '{"video1":"http://www.youtube.com/watch?v=KdxEAt91D7k&list=TLhaPoOja-0f4","video2":"http://www.youtube.com/watch?v=dVlaZfLlWQc&list=TLalXwg9bTOmo"}';
And I use jquery to add that data attribute to the div:
$(video_div).attr(key, value);
Here is my problem. After doing that I get this:
<div class="vidinfo-inline" data-video-srcs="{"video1":"http://www.youtube.com/watch?v=KdxEAt91D7k&list=TLhaPoOja-0f4","video2":"http://www.youtube.com/watch?v=dVlaZfLlWQc&list=TLalXwg9bTOmo"}"></div>
And that doesn't work putting that json in there. It has to be in single quotes. It has to look like this:
<div class="vidinfo-inline" data-video-srcs='{"video1":"http://www.youtube.com/watch?v=KdxEAt91D7k&list=TLhaPoOja-0f4","video2":"http://www.youtube.com/watch?v=dVlaZfLlWQc&list=TLalXwg9bTOmo"}'></div>
As later on I do something like this:
var video_srcs = $('.vidinfo-inline').data('video-srcs');
And that won't work unless the json is in single quotes.
Does anyone have any ideas?
EDIT:
According to jquery: http://api.jquery.com/data/#data-html5
When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string.
Thus I can't escape the double quotes, it has to be inside single quotes. I have a work around and I'll post that as an answer unless someone else has a better answer.
I have a workaround. And if anyone has a better solution, I'd love to see it.
I wrote a replace method:
var fixJson = function(str) {
return String(str)
.replace(/"{/g, "'{")
.replace(/}"/g, "}'");
};
So basically I send the html into this function and insert it into the DOM.
For example:
var html = htmlUnescape($('#temp_container').html());
html = fixJson(html);
I realize that has some code smell to it. I mean, going through everything on that element just to fix the double quotes to single quotes stinks. But for lack of other options or ideas, it works. :\
Replace the double quotes with HTML entities:
var value = '{"video1":"http://www.youtube.com/watch?v=KdxEAt91D7k&list=TLhaPoOja-0f4","video2":"http://www.youtube.com/watch?v=dVlaZfLlWQc&list=TLalXwg9bTOmo"}';
# Naive approach:
value = value.replace('&', '&').replace('"', '"');
# Using jQuery:
var $tmp = jQuery('<div></div>');
value = $tmp.text(value).html();
// Then store it as normal
I am trying to write something that would look at tweets and pull up info about stocks being mentioned in the tweet. People use $ to reference stock symbols on twitter but I cant escape the $.
I also dont want to match any price mention or anything like that so basically match $AAPL and not $1500
I was thinking it would be something like this
\b\$[a-zA-Z].*\b
if there are multiple matches id like to loop through them somehow so something like
while ((tweet = reg.exec(sym_pat)) !== null) {
//replace text with stock data.
}
This expression gives me an unexpected illegal token error
var symbol_pat = new RegExp(\b\$[a-z]*);
Thanks for the help if you want to see the next issue I ran into
Javascript AJAX scope inside of $.each Scope
Okay, you've stated that you want to replace the matches with their actual stock values. So, you need to get all of the matching elements (stock ticker names) and then for each match you're going to replace the it with the stock value.
The answer will "read" very similarly to that sentence.
Assume there's a tweet variable that is the contents of a particular tweet you're going to work on:
tweet.match(/\b\$[A-Za-z]+\b/g).forEach(function(match) {
// match looks like '$AAPL'
var tickerValue = lookUpTickerValue(match);
tweet.replace(match, tickerValue);
});
This is assuming you have some logic somewhere that will grab the ticker value for the given stock name and then replace it (it should probably return the original value if it can't find a match, so you don't mangle lovely tweets like "Barbara Streisand is $ATAN").
var symbol_pat = new RegExp('\\b\\$[a-z]+\\b','gi');
// or
var symbol_pat = /\b\$[a-z]+\b/gi;
Also, for some reason JS can not calculate the beginning of a word by \b, it just catches the one at the end.
EDIT: If you're replacing the stock symbols you can use the basic replace method by a function and replace that data with predefined values:
var symbol_pat = /(^|\s)(\$[a-z]+\b)/gi;
var stocks = {AAPL:1,ETC:2}
var str = '$aapl ssd $a a$s$etc $etc';
console.log(str);
str = str.replace(symbol_pat, function() {
var stk = arguments[2].substr(1).toUpperCase();
// assuming you want to replace $etc as well as $ETC by using
// the .toUpperCase() method
if (!stocks[stk]) return arguments[0];
return arguments[0].replace(arguments[2],stocks[stk]);
});
console.log(str);
I have an issue with jquery where elements are not found when the query string has '$' char in them -- is there a known issue? Unfortunately search engines make it so hard to searh for symbols in threads.
I have an html such as this:
<TD id="ctl00$m$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60$ctl00$ctl00_5"
class="MenuItem"
onclick="setSelectedTab('ctl00$m$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60$ctl00$ctl00_5');"
tabsrowid="ctl00$m$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60$ctl00$ctl00_"
nohide="false">...
and my jscript goes something like:
function setSelectedTab(selection) {
var ids = selection.split('/');
for (var i = 0; i<ids.length; i++) {
var item = $("#" + ids[i]);
item.addClass("selected");
$("#" + item.attr("tabsrowid")).show();
}
}
While analyzing in firebug, I see that 'item' is an empty set. If I query $('.MenuItem') for example, it correctly returns a result set with 25 matching items in the page; it appears like $(s) doesn't work when s contains $ chars in it?
What's the solution to it? Sorry if it a dumb question or well known issue -- as I said I tried to google around, but unsuccessfully.
Note: It's not an issue with javascript itself, or duplicate ids, or jquery not loaded, or anything like that. The function does get called onclick, and if I replace $('#' + ids[i]) with document.getElementById(ids[i]), it does return the correct element.
fyi, the string passed to the function setSelectedTab usually contains a hierarchical path to the TD element; though in the example TD above, the ids.length is 1.
Thanks,
Raja.
Perhaps try escaping them with backslashes
<TD id="ctl00\$m\$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60\$ctl00\$ctl00_5"
class="MenuItem"
onclick="setSelectedTab('ctl00\$m\$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60\$ctl00\$ctl00_5');"
tabsrowid="ctl00\$m\$g_cd3cd7fd_df51_4f95_9057_d98f0c1e1d60\$ctl00\$ctl00_"
nohide="false">...