近期,在实验的过程中,用到了java的正则语言表达式,类似的正则语言是str=“(A|B(\.0)?)+"的正则表达式。在读取比较小的文本进行正则匹配时,运行良好,但是遇到稍大一点的文本时,就出现了stack overflow的错误
学习了一部分自动机的知识后,结合网上的搜索内容,对这个问题谈一下认识。
由自动机的知识,可以得到如图的关系:
对于每一个正则表达式对会对应一个FA。
在语言中会将正则表达式转换为一种自动机对字符串进行识别。
在java语言中,是将正则表达式转换为NFA对语言进行识别。
自动机分为2类:DFA和NFA;
DFA是确定有穷自动机,每种状态对于输入的每个字符都有一个确定的状态转换,目标状态为一个;NFA是非确定有穷自动机,在一个状态下识别一个字符可能存在多个状态的转换。 这种形式上的差异,就造成了2种自动机对语言的识别方式、识别速度的不同。
1.DFA识别语言,是对于每一步,识别一个字符,转换为一个确定的状态,最终决定是否匹配。
2.NFA识别语言,是对于每一步,识别一个字符,转换为一个状态,如果最终没有匹配成功,则返回上一个状态,重新识别上一个识别的字符,看是否可以转换为其他的状态。
这就导致虽然NFA虽然特性丰富,但是翻来覆去的识别字符使得速度较慢,并且可能陷入递归调用而导致性能极差。
在使用正则表达式的时候,底层是通过递归方式调用执行的
,每一层的递归都会在栈线程的大小中占一定内存,如果递归的层次很多,就会报出stackOverFlowError异常。而在我们的实验中由于正则表达式较长,输入要识别的文本较大时(每一步匹配的可能性较多时),导致递归调用太深。
如何解决
在实验中,我是进行了trade off,将类似“(A|B(\.0)?)+"的正则表达式装换为“(A|B(\.0)?)"的形式,对文本进行匹配,并记录所有文本中匹配的字符串的个数为size;接着讲正则表达式进行拆分,在获取具体内容的同时,对于文本中这些部分匹配的字符串的个数进行记录,接着比较和size是否相同,一旦有不同的,则可以断定文本不符合要求。 这样可能不能保证整个文本的正确性,但可以保证一个计划项(实验中要提取的内容的最小单位)格式的正确性,提取出尽量多的符合要求的信息; 同时可以避免对于大的正则表达式使用“+”运算符,造成不必要的递归,避免栈溢出。或者也可以选择部分输入文本中的字符串,将大文本转换为多个小文本进行处理。
其次可以使用一些优化的方法,这里找到一个写的比较好的,不再赘述:
正则表达式优化
近期,在实验的过程中,用到了java的正则语言表达式,我构造的正则语言是类似str=“(… Age:((0-9?)|([1-2]0-9?)|(30(\.0)?)))+"的正则表达式。在读取比较小的文本进行正则匹配时,运行良好,但是遇到稍大一点的文本时,就出现了stack overflow的错误。经过网上的搜索...
最近遇到了一个异常:
[color=red]Exception in thread "main"
java
.lang.StackOverflowError[/color]
经查阅,是源自于
正则表达式
在匹配过程中的回溯次数过多,从而
出现
了堆
栈
溢出
。
因为在
正则表达式
的匹配过程中,需要不断地递归字符串,并根据你所写的
正则表达式
进行各种尝试与回溯。
因此,建议在利用
正则表达式
时,要...
这两天一直在做
Java
数据的抓取问题。我编写了一个程序用于实现上述功能。但在运行时
出现
了
栈
溢出
问题。查了一些资料,解决未果。最终想出了如下的思路。(我会附上我的
Java
源码)。
首先,编写了一个工具类,用于获取网站的html语言,并在此类中添加一个获取字符串str中符合
正则表达式
regexp的部分字符串的方法,代码如下:
package com.hjb;
import
java
.io.Inp
从大量doc文件(大约有150w+个文件)中读取内容,剔除部分敏感信息,存入相应目录结构的txt中。。。
经过前期大量python实验,各种问题(最大的问题是python太慢了,需要doc另存为docx,一旦与磁盘交互,程序的速度可想而知)
快要放弃之际,终于转向
java
,快速解决doc不能读取的问题,速度提上去几十甚至几百倍。
然鹅,又
出现
了新的问题。。。
剔除敏感信息需要
使用
正则表达式
匹配,替换成空字符串或者**
尽量少
使用
+或者*。虽然这两种符号用起来很方便,但是在匹配时是递归进行匹配的,所以开销会比较大。
使用
Pattern.compile()来构建新的Pattern类对象,这样做性能会比直接
使用
Matcher类要好。
想办法简化自己的
正则表达式
。
如果文本的长度过长,建议可以先手动进行简单的文本分割。比如先按段落分开,或者划分为比较短的文本块。之后再
使用
正则表达式
去匹配
Java
正则表达式
的语法与其他语言的
正则表达式
语法类似,可以
使用
java
.util.regex包中的类来实现
正则表达式
的匹配。例如,可以
使用
Pattern类来创建一个
正则表达式
模式,然后
使用
Matcher类来匹配字符串。
下面是一个简单的
Java
正则表达式
示例,用于匹配一个字符串是否包含数字:
String pattern = "\\d+";
String input = "12345";
boolean isMatch = Pattern.matches(pattern, input);
在这个例子中,
正则表达式
模式是“\d+”,它表示匹配一个或多个数字。然后
使用
Pattern.matches()方法来检查输入字符串是否与模式匹配。
如果输入字符串包含数字,isMatch变量将被设置为true,否则将被设置为false。
希望这个例子能够帮助你开始
使用
Java
正则表达式
。
Python使用matplotlib绘制并保存gif,使用animation.ArtistAnimation保存时出现[buffer not enough],[index out of range]
Python使用matplotlib绘制并保存gif,使用animation.ArtistAnimation保存时出现[buffer not enough],[index out of range]
神经网络训练出来的模型输出的结果都是相同的值
关于java的配置文件导入问题
Python使用matplotlib绘制并保存gif,使用animation.ArtistAnimation保存时出现[buffer not enough],[index out of range]
神经网络训练出来的模型输出的结果都是相同的值
关于java的配置文件导入问题