我在学习RegExp时遇到了很多麻烦,并提出了一个很好的算法来做到这一点。我有这个HTML字符串,我需要解析。请注意,当我解析它时,它仍然是一个字符串对象,而不是浏览器上的HTML,因为我需要在它到达之前解析它。 HTML看起来像这样:
<html>
<head>
<title>Geoserver GetFeatureInfo output</title>
</head>
<style type="text/css">
table.featureInfo, table.featureInfo td, table.featureInfo th {
border:1px solid #ddd;
border-collapse:collapse;
margin:0;
padding:0;
font-size: 90%;
padding:.2em .1em;
}
table.featureInfo th {
padding:.2em .2em;
font-weight:bold;
background:#eee;
}
table.featureInfo td{
background:#fff;
}
table.featureInfo tr.odd td{
background:#eee;
}
table.featureInfo caption{
text-align:left;
font-size:100%;
font-weight:bold;
text-transform:uppercase;
padding:.2em .2em;
}
</style>
<body>
<table class="featureInfo2">
<tr>
<th class="dataLayer" colspan="5">Tibetan Villages</th>
</tr>
<!-- EOF Data Layer -->
<tr class="dataHeaders">
<th>ID</th>
<th>Latitude</th>
<th>Longitude</th>
<th>Place Name</th>
<th>English Translation</th>
</tr>
<!-- EOF Data Headers -->
<!-- Data -->
<tr>
<!-- Feature Info Data -->
<td>3394</td>
<td>29.1</td>
<td>93.15</td>
<td>བསྡམས་གྲོང་ཚོ།</td>
<td>Dam Drongtso </td>
</tr>
<!-- EOF Feature Info Data -->
<!-- End Data -->
</table>
<br/>
</body>
</html>
我需要像这样:
3394,
29.1,
93.15,
བསྡམས་གྲོང་ཚོ།,
Dam Drongtso
基本上是一个数组......如果根据它的字段标题和它们以某种方式从哪个表匹配就更好了,它们看起来像这样:
Tibetan Villages
ID
Latitude
Longitude
Place Name
English Translation
找出JavaScript不支持精彩的映射是一个无赖,我有我想要的工作。然而,它是非常非常硬编码,我想我应该使用RegExp来更好地处理这个问题。不幸的是我有一个非常艰难的时间:(。这是我解析我的字符串的功能(非常丑陋的IMO):
function parseHTML(html){
//Getting the layer name
alert(html);
//Lousy attempt at RegExp
var somestring = html.replace('/m//\<html\>+\<body\>//m/',' ');
alert(somestring);
var startPos = html.indexOf('<th class="dataLayer" colspan="5">');
var length = ('<th class="dataLayer" colspan="5">').length;
var endPos = html.indexOf('</th></tr><!-- EOF Data Layer -->');
var dataLayer = html.substring(startPos + length, endPos);
//Getting the data headers
startPos = html.indexOf('<tr class="dataHeaders">');
length = ('<tr class="dataHeaders">').length;
endPos = html.indexOf('</tr><!-- EOF Data Headers -->');
var newString = html.substring(startPos + length, endPos);
newString = newString.replace(/<th>/g, '');
newString = newString.substring(0, newString.lastIndexOf('</th>'));
var featureInfoHeaders = new Array();
featureInfoHeaders = newString.split('</th>');
//Getting the data
startPos = html.indexOf('<!-- Data -->');
length = ('<!-- Data -->').length;
endPos = html.indexOf('<!-- End Data -->');
newString = html.substring(startPos + length, endPos);
newString = newString.substring(0, newString.lastIndexOf('</tr><!-- EOF Feature Info Data -->'));
var featureInfoData = new Array();
featureInfoData = newString.split('</tr><!-- EOF Feature Info Data -->');
for(var s = 0; s < featureInfoData.length; s++){
startPos = featureInfoData[s].indexOf('<!-- Feature Info Data -->');
length = ('<!-- Feature Info Data -->').length;
endPos = featureInfoData[s].lastIndexOf('</td>');
featureInfoData[s] = featureInfoData[s].substring(startPos + length, endPos);
featureInfoData[s] = featureInfoData[s].replace(/<td>/g, '');
featureInfoData[s] = featureInfoData[s].split('</td>');
}//end for
alert(featureInfoData);
//Put all the feature info in one array
var featureInfo = new Array();
var len = featureInfoData.length;
for(var j = 0; j < len; j++){
featureInfo[j] = new Object();
featureInfo[j].id = featureInfoData[j][0];
featureInfo[j].latitude = featureInfoData[j][1];
featureInfo[j].longitude = featureInfoData[j][2];
featureInfo[j].placeName = featureInfoData[j][3];
featureInfo[j].translation = featureInfoData[j][4];
}//end for
//This can be ignored for now...
var string = redesignHTML(featureInfoHeaders, featureInfo);
return string;
}//end parseHTML
因此,您可以看到该字符串中的内容是否发生了变化,我的代码将被严重破坏。我想尽可能地避免这种情况,并尝试编写更好的代码。我感谢您给我的所有帮助和建议。
答案 0 :(得分:21)
执行以下步骤:
documentFragment
为什么所有的解析工作 - 无论如何都不会起作用,因为当你拥有最好的HTML解析器时,HTML可以通过RegExp解析not? (浏览器)
答案 1 :(得分:12)
您可以使用jQuery轻松遍历DOM并自动创建具有该结构的对象。
var $dom = $('<html>').html(the_html_string_variable_goes_here);
var featureInfo = {};
$('table:has(.dataLayer)', $dom).each(function(){
var $tbl = $(this);
var section = $tbl.find('.dataLayer').text();
var obj = [];
var $structure = $tbl.find('.dataHeaders');
var structure = $structure.find('th').map(function(){return $(this).text().toLowerCase();});
var $datarows= $structure.nextAll('tr');
$datarows.each(function(i){
obj[i] = {};
$(this).find('td').each(function(index,element){
obj[i][structure[index]] = $(element).text();
});
});
featureInfo[section] = obj;
});
代码可以处理内部具有不同结构的多个表,以及每个表中的多个数据行。
featureInfo将保存最终的结构和数据,并且可以像
一样进行访问alert( featureInfo['Tibetan Villages'][0]['English Translation'] );
或
alert( featureInfo['Tibetan Villages'][0].id );
答案 2 :(得分:7)
“正确”的方法是使用DOMParser
。这样做:
var parsed=new DOMParser.parseFromString(htmlString,'text/html');
或者,如果您担心浏览器兼容性,请使用MDN documentation上的polyfill:
/*
* DOMParser HTML extension
* 2012-09-04
*
* By Eli Grey, http://eligrey.com
* Public domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*! @source https://gist.github.com/1129031 */
/*global document, DOMParser*/
(function(DOMParser) {
"use strict";
var
DOMParser_proto = DOMParser.prototype
, real_parseFromString = DOMParser_proto.parseFromString
;
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if ((new DOMParser).parseFromString("", "text/html")) {
// text/html parsing is natively supported
return;
}
} catch (ex) {}
DOMParser_proto.parseFromString = function(markup, type) {
if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
var
doc = document.implementation.createHTMLDocument("")
;
if (markup.toLowerCase().indexOf('<!doctype') > -1) {
doc.documentElement.innerHTML = markup;
}
else {
doc.body.innerHTML = markup;
}
return doc;
} else {
return real_parseFromString.apply(this, arguments);
}
};
}(DOMParser));
答案 3 :(得分:5)
如果您是在服务器端生成结果HTML的人,那么您也可以在那里生成JSON并将其与HTML内容一起传递给HTML。您不必在客户端解析任何内容,并且所有数据都可以立即用于您的客户端脚本。
您可以轻松地将table
元素中的JSON作为data
属性值:
<table class="featureInfo2" data-json="{ID:3394, Latitude:29.1, Longitude:93.15, PlaceName:'བསྡམས་གྲོང་ཚོ།', Translation:'Dam Drongtso'}">
...
</table>
或您可以将data
属性添加到包含数据的TD,并仅解析那些使用jQuery选择器并从中生成Javascript对象的属性。无需RegExp解析。
答案 4 :(得分:0)
答案 5 :(得分:0)
我有一个类似的要求,而不是有经验的JavaScript我让jquery使用parseHTML并使用find来处理它。在我的情况下,我一直在寻找具有特定类名的div。
function findElementsInHtmlString(document, htmlString, query) {
var domArray = $.parseHTML(htmlString, document),
dom = $();
// create the dom collection from the array
$.each(domArray, function(i, o) {
dom = dom.add(o);
}
// return a collection of elements that match the query
return dom.find(query);
}
var elementsWithClassBuild = findElementsInHtmlString(document, htmlString, '.build');