如何使用正则表达式匹配document.doctype.internalSubset中的所有元素

时间:2013-02-14 11:59:06

标签: javascript regex doctype

通过使用document.doctype.internalSubset,我有以下字符串,比如 str

<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >

然后,我使用正则表达式来提取结果:

result = regex.exec(str);

我的预期输出是一个数组,其中包含:

result[0] = owl "http://www.w3.org/2002/07/owl#"
result[1] = xsd "http://www.w3.org/2001/XMLSchema#"
...
result[3] = rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#"

所以,我创建了这个正则表达式:

var regex = /(?:<!ENTITY(.*?)>)*/g;

这是结果,当然,这不是我想要的:

owl "http://www.w3.org/2002/07/owl#" 

任何人都可以帮我弄清楚错误,以及如何修复所有错误吗?

请注意,我可以使用 s.indexOf()来获取 <!ENTITY &gt; 的位置,然后,使用 s.subString()来获得相同的结果,但我现在正在学习正则表达式,所以我想使用正则表达式。

--------------更新---------------

感谢Supr,我终于可以找出错误了,在我看来,在这种情况下,“*”并不意味着“匹配一次或多次”,所以不是使用/(?:<!ENTITY(.*?)>)*/g,我们将使用这个:/(?:<!ENTITY(.*?)>)/g(压缩*)然后循环遍历字符串,直到我们得到所有结果。这是来源:

var str = '<!ENTITY owl "http://www.w3.org/2002/07/owl#" >' 
    + '<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >' 
    + '<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >'
    + '<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >'

var regex = /(?:<!ENTITY(.*?)>)/g;
var results = []; 

while ((result = regex.exec(str)) != null) {
    results.push(result[1]);
}
console.log(str);
console.log("-------------------------------");
for (var i = 0; i < results.length; i++) {
    document.write(results[i] + "<br>");
}

进行测试:http://jsfiddle.net/nxhoaf/jZpHv/

顺便说一句,这是我使用s.indexOf()和递归的解决方案:

var str = '<!ENTITY owl "http://www.w3.org/2002/07/owl#" >' 
    + '<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >' 
    + '<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >'
    + '<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >'

var getNamespace = function(input) {
    var result = []; // Store the final result
    var temp = []; // Store the temporary result

    // Non trivial case
    if ((input != null) && (input.length != 0)) {

        // Get the begin and and index to extract the entity's content
        var begin = input.indexOf("<!ENTITY");
        var end = input.indexOf(">");

        if ((begin == -1) || (end == -1) || (begin >= end)) { // not found
            return null;
        }

        // Fix the begin index
        begin = begin + "<!ENTITY".length;

        // Get the content and save it to result variable
        var item = input.substring(begin, end); // ok, get one item
        // As end > begin, item is always != null
        item = item.trim(); // Normalize
        result.push(item);

        // Continue searching with the rest using
        // recursive searching
        temp = getNamespace(input.substring(end + 1)); 

        // Ok, collect all of data and then return
        if (temp != null) {
            for (var i = 0; i < temp.length; i++) {
                result.push(temp[i]);
            }
        }
        return result;
    } else { // Trivial case
        return null;
    }
}

// Parse it to get the result
result = getNamespace(str);
console.log("*************");
for (var i = 0; i < result.length; i++) {
    document.write(result[i] + "<br>");
}

您可以在此处测试:http://jsfiddle.net/nxhoaf/FNFuG/

2 个答案:

答案 0 :(得分:0)

新解决方案

似乎最后*使表达式使用整个字符串,即使返回值仅包含第一个匹配项。如果您将表达式更改为/(?:<!ENTITY(.*?)>)/g;,则可以多次应用它。正则表达式对象将跟踪上一个匹配结束的位置并从那里继续。所以:

var regex = /(?:<!ENTITY(.*?)>)/g;
var results = [];
while (result = regex.exec(str)) {
  results.push(result[1]);
}

陈旧且破败的解决方案

请尝试使用result = str.match(regex);。来自MDN docs

  

如果正则表达式包含g标志,则该方法返回包含所有匹配项的Array。如果没有匹配项,则该方法返回null。

来自同一文档的示例

var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var regexp = /[A-E]/gi;
var matches_array = str.match(regexp);

// matches_array now equals ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

答案 1 :(得分:0)

var arr = Array();

传递正则表达式模式

var pattern= /(?:<!ENTITY(.*?)>)*/g;  //your pattern

arr = string.match( pattern )

希望这对您有用..请访问该数组