When using Java to analyze HTML text, if you want to extract content between nodes with nested structures, you cannot directly use regular expressions for processing, because the regular expressions in Java do not support descriptions of nested structures, although Perl ,. net and PHP support. In this case, you can use a regular expression to find the position of the node in the string, and then perform matching on the node to retrieve the content between matching nodes to process the nested structure.
For example
data=<div><div>abcd<div></div><form><input type='button' value='submit'/></form></div></div><div>1234</div>
To retrieve the content between <div> </div> and return two strings.
<Div> ABCD <div> </div> <form> <input type = 'button 'value = 'submit '/> </form> </div>And 1234.
The source code is as follows:
To record the value and position of a node in a string, define a class and save the information:
public class Tag {public Tag(String value, int beginPos, int endPos) {super();this.value = value;this.beginPos = beginPos;this.endPos = endPos;}private String value;private int beginPos;private int endPos;public String getValue() {return value;}public void setValue(String value) {this.value = value;}public int getBeginPos() {return beginPos;}public void setBeginPos(int beginPos) {this.beginPos = beginPos;}public int getEndPos() {return endPos;}public void setEndPos(int endPos) {this.endPos = endPos;}}The function for getting content between nodes from a string is as follows:
/*** Obtain the content between strings. If the content contains nesting, returns the outermost nested content ** @ Param data * @ Param stag Start Node string * @ Param etag End Node string * @ return */public list <string> get (string data, string stag, string etag) {// stores the Start Node, used to match the end node with the stack <tag> Work = new stack <tag> (); // Save the list of all start and end nodes <tag> alltags = new arraylist <tag> (); // Add the escape character string nstag = stag before the metacharacters. replaceall ("([\\! \: \ * \. \ + \ (\] \ [\? \\{\}\\\\\\\\|\\\\]) "," \\\\$ 1 "); string netag = etag. replaceall ("([\\! \: \ * \. \ + \ (\] \ [\? \\{\}\\\\\\\\|\\\\]) "," \\\\\ $1 "); string Reg = "((?: "+ Nstag +") | (?: "+ Netag +") "; pattern P = pattern. compile (Reg, pattern. case_insensitive | pattern. multiline); matcher M = P. matcher (data); While (M. find () {tag = new tag (M. group (0), M. start (), M. end (); alltags. add (TAG) ;}// Save the content between nodes that start and end, excluding the node list <string> result = new arraylist <string> (); For (tag t: alltags) {If (stag. equalsignorecase (T. getvalue () {work. push (t);} else if (etag. equalsignorecase (T. getvalue () {// If the stack is empty, it indicates If (work. empty () {Throw new runtimeexception ("POS" + T. getbeginpos () + "tag not match start tag. ");} tag otag = work. pop (); // If the stack is empty, it matches if (work. empty () {string sub = data. substring (otag. getendpos (), T. getbeginpos (); result. add (sub) ;}}// if the stack is not empty at this time, if (! Work. empty () {tag T = work. pop (); throw new runtimeexception ("tag" + T. getvalue () + "not match. ");} return result ;}The function returns a list of content strings between nodes.
For example, call get (data, "<div>", "</div>") to return a list containing two elements:
<div>abcd<div></div><form><input type='button' value='>'/></form></div>, 1234
Note that if the node contains the metacharacters of the regular expression, you need to add the Escape Character \ before the metacharacters. This function is implemented in line 16 and 17 of the source code.