Java 为多个模式分析输入流
我正在分析InputStream的某些模式,以从中提取值,例如Java 为多个模式分析输入流,java,regex,pattern-matching,inputstream,Java,Regex,Pattern Matching,Inputstream,我正在分析InputStream的某些模式,以从中提取值,例如 <span class="filename"><a href="http://example.com/foo">foo</a> <span class="filename" id="234217"><a href="http://example.com/foo">foo</a> 在这一点上,我确信我会重新发明轮子,因为这肯定会在以前完成,而且我真的不想从一开
<span class="filename"><a href="http://example.com/foo">foo</a>
<span class="filename" id="234217"><a href="http://example.com/foo">foo</a>
在这一点上,我确信我会重新发明轮子,因为这肯定会在以前完成,而且我真的不想从一开始就编写自己的正则表达式解析器。然而,我找不到任何能满足我所需的东西。不幸的是,
Scanner
类只匹配一种模式,而不是模式列表,我可以使用什么替代方案?它不应该太重,而且可以与Android一起使用。API似乎正是您所需要的。您必须使用或(|)分隔的模式字符串
但是,这种模式很快就会变得非常复杂。您的意思是要将任何
元素与给定的类
属性相匹配,而不考虑它可能具有的其他属性?这很简单:
Scanner sc = new Scanner(new File("test.txt"), "UTF-8");
Pattern p = Pattern.compile(
"<span[^>]*class=\"filename\"[^>]*>\\s*<a[^>]*href=\"([^\"]+)\""
);
while (sc.findWithinHorizon(p, 0) != null)
{
MatchResult m = sc.match();
System.out.println(m.group(1));
}
Scanner sc=新扫描仪(新文件(“test.txt”),“UTF-8”);
模式p=Pattern.compile(
“]*类=\”文件名\“[^>]*>\\s*]*href=\”([^\“]+)\”
);
while(sc.findWithinHorizon(p,0)!=null)
{
MatchResult m=sc.match();
系统输出println(m.group(1));
}
文件“test.txt”包含问题的文本,输出为:
http://example.com/foo
and closing
http://example.com/foo
http://example.com/foo
和结束
http://example.com/foo你认为这一切都是正确的:“你所说的是一个标记化和解析的问题,因此我建议你考虑javaC. 当您学习理解JavaCC的语法时,它有一个学习曲线,下面是一个让您开始学习的实现 语法是的精简版本。您可以添加更多产品以匹配其他模式
options {
JDK_VERSION = "1.5";
static = false;
}
PARSER_BEGIN(eg1)
import java.util.*;
public class eg1 {
private String currentTag;
private String currentSpanClass;
private String currentHref;
public static void main(String args []) throws ParseException {
System.out.println("Starting parse");
eg1 parser = new eg1(System.in);
parser.parse();
System.out.println("Finishing parse");
}
}
PARSER_END(eg1)
SKIP :
{
< ( " " | "\t" | "\n" | "\r" )+ >
| < "<!" ( ~[">"] )* ">" >
}
TOKEN :
{
<STAGO: "<" > : TAG
| <ETAGO: "</" > : TAG
| <PCDATA: ( ~["<"] )+ >
}
<TAG> TOKEN [IGNORE_CASE] :
{
<A: "a" > : ATTLIST
| <SPAN: "span" > : ATTLIST
| <DONT_CARE: (["a"-"z"] | ["0"-"9"])+ > : ATTLIST
}
<ATTLIST> SKIP :
{
< " " | "\t" | "\n" | "\r" >
| < "--" > : ATTCOMM
}
<ATTLIST> TOKEN :
{
<TAGC: ">" > : DEFAULT
| <A_EQ: "=" > : ATTRVAL
| <#ALPHA: ["a"-"z","A"-"Z","_","-","."] >
| <#NUM: ["0"-"9"] >
| <#ALPHANUM: <ALPHA> | <NUM> >
| <A_NAME: <ALPHA> ( <ALPHANUM> )* >
}
<ATTRVAL> TOKEN :
{
<CDATA: "'" ( ~["'"] )* "'"
| "\"" ( ~["\""] )* "\""
| ( ~[">", "\"", "'", " ", "\t", "\n", "\r"] )+
> : ATTLIST
}
<ATTCOMM> SKIP :
{
< ( ~["-"] )+ >
| < "-" ( ~["-"] )+ >
| < "--" > : ATTLIST
}
void attribute(Map<String,String> attrs) :
{
Token n, v = null;
}
{
n=<A_NAME> [ <A_EQ> v=<CDATA> ]
{
String attval;
if (v == null) {
attval = "#DEFAULT";
} else {
attval = v.image;
if( attval.startsWith("\"") && attval.endsWith("\"") ) {
attval = attval.substring(1,attval.length()-1);
} else if( attval.startsWith("'") && attval.endsWith("'") ) {
attval = attval.substring(1,attval.length()-1);
}
}
if( attrs!=null ) attrs.put(n.image.toLowerCase(),attval);
}
}
void attList(Map<String,String> attrs) : {}
{
( attribute(attrs) )+
}
void tagAStart() : {
Map<String,String> attrs = new HashMap<String,String>();
}
{
<STAGO> <A> [ attList(attrs) ] <TAGC>
{
currentHref=attrs.get("href");
if( currentHref != null && "filename".equals(currentSpanClass) )
{
System.out.println("Found URL: "+currentHref);
}
}
}
void tagAEnd() : {}
{
<ETAGO> <A> <TAGC>
{
currentHref=null;
}
}
void tagSpanStart() : {
Map<String,String> attrs = new HashMap<String,String>();
}
{
<STAGO> <SPAN> [ attList(attrs) ] <TAGC>
{
currentSpanClass=attrs.get("class");
}
}
void tagSpanEnd() : {}
{
<ETAGO> <SPAN> <TAGC>
{
currentSpanClass=null;
}
}
void tagDontCareStart() : {}
{
<STAGO> <DONT_CARE> [ attList(null) ] <TAGC>
}
void tagDontCareEnd() : {}
{
<ETAGO> <DONT_CARE> <TAGC>
}
void parse() : {}
{
(
LOOKAHEAD(2) tagAStart() |
LOOKAHEAD(2) tagAEnd() |
LOOKAHEAD(2) tagSpanStart() |
LOOKAHEAD(2) tagSpanEnd() |
LOOKAHEAD(2) tagDontCareStart() |
LOOKAHEAD(2) tagDontCareEnd() |
<PCDATA>
)*
}
选项{
JDK_VERSION=“1.5”;
静态=假;
}
解析器_BEGIN(eg1)
导入java.util.*;
公共类eg1{
私有字符串currentTag;
私有字符串类;
私有字符串currentHref;
公共静态void main(字符串args[])引发异常{
System.out.println(“开始解析”);
eg1解析器=新的eg1(System.in);
parser.parse();
System.out.println(“完成解析”);
}
}
语法分析器(eg1)
跳过:
{
<(“|”\t“|”\n“|”\r”)+>
| < ""] )* ">" >
}
代币:
{
:标记
|:标记
|
}
令牌[忽略大小写]:
{
:收件人名单
|:收件人名单
|:收件人名单
}
跳过:
{
<“”|“\t”|“\n”|“\r”>
|<“-”>:ATTCOMM
}
代币:
{
:默认值
|:ATTRVAL
|
|
|
|
}
代币:
{
“,“\”,“,”,“\t”,“\n”,“\r”])+
>:收件人名单
}
跳过:
{
< ( ~["-"] )+ >
| < "-" ( ~["-"] )+ >
|<“-”>:附件列表
}
无效属性(映射属性):
{
令牌n,v=null;
}
{
n=[v=]
{
字符串attval;
如果(v==null){
attval=“#默认值”;
}否则{
attval=v.image;
if(attval.startsWith(“\”)和&attval.endsWith(“\”)){
attval=attval.substring(1,attval.length()-1);
}else if(attval.startsWith(“”)和attval.endsWith(“”){
attval=attval.substring(1,attval.length()-1);
}
}
if(attrs!=null)attrs.put(n.image.toLowerCase(),attval);
}
}
无效attList(映射属性):{}
{
(属性(属性)+
}
void tagAStart():{
Map attrs=new HashMap();
}
{
[收件人名单(ATTR)]
{
currentHref=attrs.get(“href”);
如果(currentHref!=null&“filename”.equals(currentSpanClass))
{
System.out.println(“找到的URL:+currentHref”);
}
}
}
void tagAEnd():{}
{
{
currentHref=null;
}
}
void tagSpanStart():{
Map attrs=new HashMap();
}
{
[收件人名单(ATTR)]
{
currentSpanClass=attrs.get(“类”);
}
}
void tagSpanEnd():{}
{
{
currentSpanClass=null;
}
}
void tagDontCareStart():{}
{
[收件人列表(空)]
}
void tagdontcreend():{}
{
}
void parse():{}
{
(
前瞻(2)tagAStart()|
前瞻性(2)塔加恩德()|
前瞻(2)tagSpanStart()|
前瞻(2)标记span结束()|
前瞻(2)tagDontCareStart()|
前瞻(2)tagdontcreend()|
)*
}
我想知道您的输入在XML Sense中是否格式正确。不,html可能无效。不,我还想匹配其他模式,如…(值)或文本(文本)区分不同的模式。嗯,这似乎有些过分,如果我做对了,如果规范发生变化,我还必须重新编译应用程序,而不仅仅是调整配置文件并重新加载。