我想解析字符串以从它们获得字段。字符串的格式(来自数据集)是这样的( ->表示一个选项卡,*表示一个空格):
Date(yyyymmdd)->Date(yyyymmdd)->*City,*State*-->Description我只对第一次约会和国家感兴趣。我试过这样做:
String txt="19951010 19951011 Red City, WI Description";
String re1="(\\d+)"; // Integer Number 1
String re2=".*?"; // Non-greedy match on filler
String re3="(?:[a-z][a-z]+)"; // Uninteresting: word
String re4=".*?"; // Non-greedy match on filler
String re5="(?:[a-z][a-z]+)"; // Uninteresting: word
String re6=".*?"; // Non-greedy match on filler
String re7="((?:[a-z][a-z]+))"; // Word 1
Pattern p = Pattern.compile(re1+re2+re3+re4+re5+re6+re7,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(txt);
if (m.find())
{
String int1=m.group(1);
String word1=m.group(2);
System.out.print("("+int1.toString()+")"+"("+word1.toString()+")"+"\n");
}如果城市有两个词(红色城市),那么国家就被恰当地提取出来,但是如果城市只有一个词,它就无效。我不明白,我不需要使用regex,也可以接受任何其他建议。谢谢。
发布于 2013-11-17 02:21:14
问题:
您的问题是,当前正则表达式中的每个组件实际上都匹配一个数字或a字,用任何不是a的东西分隔,其中包括逗号。所以你对一个两个词的城市的角色是:
Input:
19951010 19951011 Red City, WI Description
Your components:
String re1="(\\d+)"; // Integer Number 1
String re2=".*?"; // Non-greedy match on filler
String re3="(?:[a-z][a-z]+)"; // Uninteresting: word
String re4=".*?"; // Non-greedy match on filler
String re5="(?:[a-z][a-z]+)"; // Uninteresting: word
String re6=".*?"; // Non-greedy match on filler
String re7="((?:[a-z][a-z]+))"; // Word 1
What they match:
re1: "19951010"
re2: " 19951011 "
re3: "Red" (stops at non-letter, e.g. whitespace)
re4: " "
re5: "City" (stops at non-letter, e.g. the comma)
re6: ", " (stops at word character)
re7: "WI"但只有一个词的城市:
Input:
19951010 19951011 Pittsburgh, PA Description
What they match:
re1: "19951010"
re2: " 19951011 "
re3: "Pittsburgh" (stops at non-letter, e.g. the comma)
re4: ","
re5: "PA" (stops at non-letter, e.g. whitespace)
re6: " " (stops at word character)
re7: "Description" (but you want this to be the state)
解决方案:
你应该做两件事。首先,稍微简化一下正则表达式;您将疯狂地指定贪婪还是不情愿,等等,只需使用贪婪的模式。第二,考虑最简单的表达规则的方法。
你的规矩是:
因此,建立一个坚持这一点的正则表达式。你可以跳过第二个数字,就像你现在做的那样,走捷径,但请注意,你确实失去了对以数字开头的城市的支持(这很可能不会发生)。你也不关心国家。因此,例如:
String re1 = "(\\d+)"; // match first number
String re2 = "[^,]*"; // skip everything thats not a comma
String re3 = ","; // skip the comma
String re4 = "[\\s]*"; // skip whitespace
String re5 = "([a-z]+)"; // match letters (state)
String regex = re1 + re2 + re3 + re4 + re5;还有其他选项,但我个人认为正则表达式对于这样的事情非常简单。您可以使用split()的各种组合,就像其他海报详细介绍的那样。您可以使用indexOf()直接查找逗号和空格并提取子字符串。您甚至可以说服Scanner或StringTokenizer或StreamTokenizer为您工作。然而,正则表达式存在以解决类似这样的问题,并且是一个很好的工作工具。
下面是一个使用StringTokenizer的示例
StringTokenizer t = new StringTokenizer(txt, " \t");
String date = t.nextToken();
t.nextToken(); // skip second date
t.nextToken(","); // change delimiter to comma and skip city
t.nextToken(" \t"); // back to whitespace and skip comma
String state = t.nextToken();不过,我觉得规则表达得更清楚了。
顺便说一句,对于将来的调试,有时只需要打印出所有的捕获组就可以帮助您深入了解什么是匹配的。一种很好的方法是将正则表达式的每个组件暂时放到一个捕获组中,然后全部打印出来。
发布于 2013-11-17 02:33:23
不用这么复杂。你可以在空格上分开!
//s is your string
String[] first = s.split("\\s*,\\s*")
String[] firstHalf = first[0].split("\\s+")
String[] secondHalf = first[1].split("\\s+")
String date = firstHalf[0]
String state = secondHalf[0]现在你有自己的date和state了!你想怎么做就怎么做。
https://stackoverflow.com/questions/20026415
复制相似问题