我正在开发一个用于将短信解析为字符串的应用程序,我希望将其存储在sqlite数据库中。
以下是短信的外观示例。 广播时间付款的样本。
Airtime payment made for UGX5,000 to KKL(0909xxxx).
Your Balance is UGX10,000.
Thank you for using KKL MobileMoney.
手机存款样本
You have received UGX100,000 from 09006700. Reason:J.
Your balance is UGX170,000.
移动货币发送示例
You have sent UGX10,000 to 08970000.
Reason:j.
Your balance is UGX120,000.
Thank you for using KKL MobileMoney.
我感兴趣的是: - 发送/接收/支付的金额。 - 收到/发送/付款的号码。 - 原因 - 平衡。
到目前为止,我已尝试使用分割功能。
虽然它不一致。我正在使用字符串标记的数组索引,但是在某些字符串上我得到一个索引输出绑定异常,但它在某些字符串上有效。
这是我到目前为止的代码......但是工作不一致!
if (str.startsWith(RECEIVED))
{
// for mm deposit
Log.e("msg", str);
String delimeter="[ .]+";
String[] tokens= str.split(delimeter);
for (int i=0;i < tokens.length;i++)
{
Log.e("Test",tokens[i]);
}
String amount =tokens[3];
String reason =tokens[6].trim();
String number=tokens[5];
String balance=tokens[11];
Log.e("Amount",amount);
Log.e("reasons",reason);
Log.e("number",number);
Log.e("balance",balance);
String type="Deposit";
db.addrecord(amount, type, reason, number, balance);
db.close();
}
else if(str.startsWith(SEND))
{
// for sent sms
Log.e("msg", str);
String delimeter="[ .]+";
String[] tokens= str.split(delimeter);
for (int i=0;i < tokens.length;i++)
{
Log.e("Test",tokens[i]);
}
String amount =tokens[3];
String reason =tokens[6].trim();
String number=tokens[5];
String balance=tokens[11];
Log.e("Amount",amount);
Log.e("reasons",reason);
Log.e("number",number);
Log.e("balance",balance);
String type="Payment";
db.addrecord(amount, type, reason, number, balance);
db.close();
}
else if(str.startsWith(AIRTIMEPAYMENT))
{ // for airtime sms
Log.e("msg", str);
String delimeter="[ .]+";
String[] tokens= str.split(delimeter);
for (int i=0;i < tokens.length;i++)
{
Log.e("Test",tokens[i]);
}
String amount =tokens[4];
String reason =tokens[0]+ " "+ tokens[1];
String number=tokens[7];
String balance=tokens[11];
Log.e("Amount",amount);
Log.e("reasons",reason);
Log.e("number",number);
Log.e("balance",balance);
String type="Air Time ";
db.addrecord(amount, type, reason, number, balance);
db.close();
}
有关如何最好地处理解析的任何提示/建议?
我是java / android程序员初学者!
罗纳德
以下是我对
进行的编辑private Map<String, String> parseSms(String s){
Map<String, String> ret = new HashMap<String, String>();
s = s.replace("\n", "");
StringTokenizer t = new StringTokenizer(s, ".");
while (t.hasMoreTokens()){
String b = t.nextToken().trim();
if (b.startsWith("You have sent") ||(b.startsWith("You have received"))){
String type = getType(b);
String parsed = parseAmount(b);
String number = parseNumber(b);
ret.put("amount", parsed);
ret.put("number", number);
ret.put("type", type);
}else if(b.startsWith("Your")){//balance
String parsed = parseAmount(b);
ret.put("balance", parsed);
}else if (b.startsWith("Reason")){
ret.put("reason", b.toString());
}
else if( b.startsWith("Airtime"))
{
String type = getType(b);
String parsed = parseAmount(b);
String number = parseNumber(b);
ret.put("amount", parsed);
ret.put("number", number);
ret.put("reason", "Air Time Payment");
ret.put("type", type);
}else if(b.startsWith("Your")){//balance
String parsed = parseAmount(b);
ret.put("balance", parsed);
}
}
return ret;
}
它解决了这个问题。
答案 0 :(得分:3)
解析此类文本的最佳方法是使用正则表达式(RegEx)。
所以..你在你的应用程序中定义了几个正则表达式...并检查字符串是否匹配...如果是......那么你找到它了!。
花一些时间学习正则表达式..它们在解析时非常用。您可以使用网站http://rubular.com/来验证/测试正则表达式。
用于使用正则表达式解析/匹配字符串的代码的一个示例:
Pattern p = Pattern.compile("^(\\d+)\\s(\\d+)\\s(.*)$");
Matcher m = p.matcher(strAlarm);
if (m.matches(){
int notificationId = Integer.parseInt(m.group(1));
long timeInMsec = Long.parseLong(m.group(2));
String message = m.group(3);
....
}
上面的例子解析了这种字符串“323 432 123 zxchzxc any kjhzcx”
作为一个小帮助..让我们解析你的第二个例子。
Pattern p=Pattern.compile("^You\\s+have\\s+received\\s+(\\S+)\\sfrom\\s+(\\d+)\\.\\sReason:\\w\\.\\s*Your\\sbalance\\sis\\s(\\S+)");
Matcher m = p.matcher(smsTextHere);
if (m.matches(){
//m.group(1) -- is string containing UGX100,000
//m.group(1) -- is string containing 09006700
//m.group(1) -- is string containing UGX170,000.
}
答案 1 :(得分:2)
这是解析更强大的解决方案。
用您的常量替换相关的字符串。在循环方面,使用Map比String []更安全。您也可以使用与regexp匹配。
private void test(){
String sms = "You have sent UGX10,000 to 08970000.\n" +
"Reason:j.\n" +
"Your balance is UGX120,000.\n" +
"Thank you for using KKL MobileMoney.";
/*String rec = "You have received UGX100,000 from 09006700. Reason:J.\n" +
"Your balance is UGX170,000.";
String air = "Airtime payment made for UGX5,000 to KKL(0909xxxx).\n" +
"Your Balance is UGX10,000.\n" +
"Thank you for using KKL MobileMoney.";
*/
Map<String, String> data = parseSms(sms);
saveToDB(data);
}
private void saveToDB(Map<String, String> data){
db.addrecord(data.get("amount"), data.get("type"), data.get("reason"), data.get("number"), data.get("balance"));
db.close();
}
private Map<String, String> parseSms(String s){
Map<String, String> ret = new HashMap<String, String>();
s = s.replace("\n", "");
StringTokenizer t = new StringTokenizer(s, ".");
while (t.hasMoreTokens()){
String b = t.nextToken().trim();
if (b.startsWith("You have sent") || (b.startsWith("Airtime") || (b.startsWith("You have received")))){
String type = getType(b);
String parsed = parseAmount(b);
String number = parseNumber(b);
ret.put("amount", parsed);
ret.put("number", number);
ret.put("type", type);
}else if(b.startsWith("Your")){//balance
String parsed = parseAmount(b);
ret.put("balance", parsed);
}else if (b.startsWith("Reason")){
ret.put("reason", b.toString());
}
}
return ret;
}
private String getType(String s){
if (s.startsWith("You have sent"))//Use your constants
return "Payment";
else if (s.startsWith("Airtime"))
return "Air time";
else if (s.startsWith("You have received"))
return "Deposit";
return "Unknown";
}
private String parseNumber(String s){
String numberFragment = s.substring(s.lastIndexOf(' '), s.length());//extract number
return numberFragment;
}
private String parseAmount(String s){
char[] arr = s.toCharArray();
StringBuffer sb = new StringBuffer();
boolean parsingNumber = false;
for (char c: arr){
if (Character.isDigit(c))
parsingNumber = true;
if (Character.isLetter(c) && c != ',' )
parsingNumber = false;
if (parsingNumber && c == ' ')//we have reached end of digit series
break; //done
if (parsingNumber)
sb.append(c);
}
return sb.toString();
}