Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java';s Regex有时抛出堆栈溢出异常?_Java_Regex_Stack Overflow - Fatal编程技术网

为什么java';s Regex有时抛出堆栈溢出异常?

为什么java';s Regex有时抛出堆栈溢出异常?,java,regex,stack-overflow,Java,Regex,Stack Overflow,我正在尝试为HTML标记创建一个正则表达式。 到目前为止,我创建的正则表达式是)|>),当我在线测试它时,它工作得非常好;但当我使用Java正则表达式测试它时,它有时抛出StackOverflower错误,有时则没有 我正在使用此代码进行测试: public static void parseHtml(String urlString){ new Thread(new Runnable() { @Override public void run() {

我正在尝试为HTML标记创建一个正则表达式。 到目前为止,我创建的正则表达式是
)|>)
,当我在线测试它时,它工作得非常好;但当我使用Java正则表达式测试它时,它有时抛出StackOverflower错误,有时则没有

我正在使用此代码进行测试:

public static void parseHtml(String urlString){
    new Thread(new Runnable() {
        @Override
        public void run() {
            int count = 0;
            int count2 = 0;
            String htmlScript = downloadWebPage(urlString);
            Matcher matcher = Pattern.compile("<(/?)(\\w+?)(\\s(.*?))*?((/>)|>)",
                                              Pattern.DOTALL).matcher(htmlScript);
            while(matcher.find()) {
                System.out.println(matcher.group());
            }
        }
    }).start();
}
publicstaticvoidparsehtml(字符串urlString){
新线程(newrunnable()){
@凌驾
公开募捐{
整数计数=0;
int count2=0;
字符串htmlScript=下载网页(urlString);
Matcher Matcher=Pattern.compile(“)|>)”,
Pattern.DOTALL.matcher(htmlScript);
while(matcher.find()){
System.out.println(matcher.group());
}
}
}).start();
}
所以,我的问题是: 为什么Java的正则表达式引擎有时抛出StackOverflower错误,有时却没有


注意:我使用了相同的测试输入(相同的URL),它抛出了错误,稍后再次测试,效果很好。

在我测试的输入的基础上,它工作正常,我无法重现错误,以下是实现:

public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            String htmlScript = downloadWebPage("https://stackoverflow.com/questions/13684468/java-runnable-run-method-returning-a-value");
            Matcher matcher = Pattern.compile("<(/?)(\\w+?)(\\s(.*?))*?((/>)|>)",
                                              Pattern.DOTALL).matcher(htmlScript);
            while(matcher.find()) {
                System.out.println(matcher.group());
            }
        }
    }).start();

}

private static String downloadWebPage(String urlString) {
    StringBuilder sb = new StringBuilder();
    try {
        URL u = new URL(urlString);
        BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            sb.append(inputLine);
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}
publicstaticvoidmain(字符串[]args){
新线程(newrunnable()){
@凌驾
公开募捐{
字符串htmlScript=下载网页(“https://stackoverflow.com/questions/13684468/java-runnable-run-method-returning-a-value");
Matcher Matcher=Pattern.compile(“)|>)”,
Pattern.DOTALL.matcher(htmlScript);
while(matcher.find()){
System.out.println(matcher.group());
}
}
}).start();
}
私有静态字符串下载网页(字符串URL字符串){
StringBuilder sb=新的StringBuilder();
试一试{
URL u=新URL(URL字符串);
BufferedReader in=新的BufferedReader(新的InputStreamReader(u.openStream());
字符串输入线;
而((inputLine=in.readLine())!=null){
某人附加(输入线);
}
in.close();
}捕获(例外e){
e、 printStackTrace();
}
使某人返回字符串();
}

以下是输出:

根据您的输入,我测试了它,它工作正常,我无法重现错误,以下是实现:

public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            String htmlScript = downloadWebPage("https://stackoverflow.com/questions/13684468/java-runnable-run-method-returning-a-value");
            Matcher matcher = Pattern.compile("<(/?)(\\w+?)(\\s(.*?))*?((/>)|>)",
                                              Pattern.DOTALL).matcher(htmlScript);
            while(matcher.find()) {
                System.out.println(matcher.group());
            }
        }
    }).start();

}

private static String downloadWebPage(String urlString) {
    StringBuilder sb = new StringBuilder();
    try {
        URL u = new URL(urlString);
        BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            sb.append(inputLine);
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}
publicstaticvoidmain(字符串[]args){
新线程(newrunnable()){
@凌驾
公开募捐{
字符串htmlScript=下载网页(“https://stackoverflow.com/questions/13684468/java-runnable-run-method-returning-a-value");
Matcher Matcher=Pattern.compile(“)|>)”,
Pattern.DOTALL.matcher(htmlScript);
while(matcher.find()){
System.out.println(matcher.group());
}
}
}).start();
}
私有静态字符串下载网页(字符串URL字符串){
StringBuilder sb=新的StringBuilder();
试一试{
URL u=新URL(URL字符串);
BufferedReader in=新的BufferedReader(新的InputStreamReader(u.openStream());
字符串输入线;
而((inputLine=in.readLine())!=null){
某人附加(输入线);
}
in.close();
}捕获(例外e){
e、 printStackTrace();
}
使某人返回字符串();
}

以下是输出:

我认为Java在某些情况下不喜欢交替是出了名的
存在潜在回溯问题的地方

因此,这一部分
(\s(.*?))*?
在回溯过程中造成了撤消负担
机制

 (                             # (3 start)
      \s
      ( .*? )                       # (4)
 )*?                           # (3 end)
其中,最终结果是嵌套的可选量词。
它可以减少为
([\S\S]*?)
,而不存在嵌套问题

此外,此部分
(/>)|>)
可以简化为
(/?>)
而无需
对于另一个堆栈帧,通过交替

总的来说,你并不真的需要捕获组


如果您只需要对标记进行pars,这是html的初始级别
解析,然后使用正则表达式是可以的

如果您想做的不仅仅是解析单个标记,那么就需要一个DOM解析器

我发现这个正则表达式将解析所有单独的html/xml标记

在本次会议上,除了除了上述代码之外,其他一些国家的政府官员们还将在以下几几名““““,”除了除了除了除了除了除了上述代码之外,其他一些国家的代码除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了上述几几几之外之外之外之外之外之外之外的其他其他其他外外的其他外的其他外的其他外的其他外,其他外外,其他外,其他其他几几几几几几几几几几名外,其他外,,,,,,,,,,,,““““““,除除除除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了除了\\[CDATA\\[[\\S\\S]*?\\]\\\]\\\])|(?:--[\\S\\S]*?-)|(?:ATTLIST[\\S\\S]*?)|(?:实体[\\S]*?)(?:元素[\\S\\S]*?)>“

扩大

 <
 (?:
      (?:
           (?:
                # Invisible content; end tag req'd
                (                             # (1 start)
                     script
                  |  style
                  |  object
                  |  embed
                  |  applet
                  |  noframes
                  |  noscript
                  |  noembed 
                )                             # (1 end)
                (?:
                     \s+ 
                     (?>
                          " [\S\s]*? "
                       |  ' [\S\s]*? '
                       |  (?:
                               (?! /> )
                               [^>] 
                          )?
                     )+
                )?
                \s* >
           )

           [\S\s]*? </ \1 \s* 
           (?= > )
      )

   |  (?: /? [\w:]+ \s* /? )
   |  (?:
           [\w:]+ 
           \s+ 
           (?:
                " [\S\s]*? " 
             |  ' [\S\s]*? ' 
             |  [^>]? 
           )+
           \s* /?
      )
   |  \? [\S\s]*? \?
   |  (?:
           !
           (?:
                (?: DOCTYPE [\S\s]*? )
             |  (?: \[CDATA\[ [\S\s]*? \]\] )
             |  (?: -- [\S\s]*? -- )
             |  (?: ATTLIST [\S\s]*? )
             |  (?: ENTITY [\S\s]*? )
             |  (?: ELEMENT [\S\s]*? )
           )
      )
 )
 >
<
(?:
(?:
(?:
#不可见内容;需要结束标记
(#(1开始)
剧本
|风格
|反对
|嵌入
|小程序
|无框
|noscript
|诺姆贝德
)#(一完)
(?:
\s+
(?>
“[\S\S]*?”
|“[\S\S]*?”
|  (?:
(?! /> )
[^>] 
)?
)+
)?
\s*>
)
[\S\S]*?)
)
|(?:/?[\w::+\s*/?)
|  (?:
[\w:]
\s+
(?:
“[\S\S]*?”
|“[\S\S]*?”
|  [^>]? 
)+
\s*/?
)
|  \? [\S\S]*?\?
|  (?:
!
(?:
(?:DOCTYPE[\S\S]*?)
|(?:\[CDATA\[\S\S]*?\]\]
|(?:--[\S\S]*?--)
|(?:ATTLIST[\S\S]*?)
|(?:实体[\S\S]*?)
|