How to use regex to match all document.doctype.internalSubset elements
Using document.doctype.internalSubset I have the following line 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#" >
Then I use regex to extract the result:
result = regex.exec(str);
My expected output is an array where:
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#"
So, I create this regex:
var regex = /(?:<!ENTITY(.*?)>)*/g;
And here's the result, of course, that's not what I want:
owl "http://www.w3.org/2002/07/owl#"
Can anyone help me figure out the errors and how to fix them all?
Note that I can use s.indexOf () to get the position and <!ENTITY
and then use s.subString () to get the same result, but now I'm learning regex, so I want to use regex.
-------------- Update ---------------
Thanks to Supr I can finally figure out the error, it seems to me that in this case "*" does not mean "match one or more times", so instead of using /(?:<!ENTITY(.*?)>)*/g
ll use this: /(?:<!ENTITY(.*?)>)/g
(suppress *) and then iterate over the string until we we get the whole result. Here is the source:
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>");
}
For testing: http://jsfiddle.net/nxhoaf/jZpHv/
By the way, here is my solution using s.indexOf () and recursion:
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 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>");
}
you can test it here: http://jsfiddle.net/nxhoaf/FNFuG/
source to share
New solution
It looks like the latter *
makes the expression consume the entire string, even if the return value only includes the first match. If you change the expression to /(?:<!ENTITY(.*?)>)/g;
, you can apply it multiple times. The regex object will keep track of where the last match ended and continue from there. So:
var regex = /(?:<!ENTITY(.*?)>)/g;
var results = [];
while (result = regex.exec(str)) {
results.push(result[1]);
}
An old and ruined solution
Try using instead result = str.match(regex);
. From MDN docs :
If the regular expression includes the g flag, the method returns an array containing all matches. If there were no matches, the method returns null.
Example from the same doc
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']
source to share