你需要远离让正则表达式控制你。如果您以另一种方式定义您的结构(我使用enum
下面的方式),您可以从中派生正则表达式和格式化程序,那么不仅代码将变得更具可扩展性,而且您还可以从中制作编组器和解组器.
这样的事情可能是一个好的开始:
public class BankRecords {
static enum AccountField {
BANK_ID("\\d", 3) {
@Override
void fill ( Account a, String s ) {
a.bankId = s;
}
},
ACCOUNT_ID("\\d", 12) {
@Override
void fill ( Account a, String s ) {
a.accountID = s;
}
},
COMPANY_NAME(".", 20) {
@Override
void fill ( Account a, String s ) {
a.companyName = s;
}
},
MONTH("\\d", 2) {
@Override
void fill ( Account a, String s ) {
a.month = s;
}
},
DAY("\\d", 2) {
@Override
void fill ( Account a, String s ) {
a.day = s;
}
},
YEAR("\\d", 2) {
@Override
void fill ( Account a, String s ) {
a.year = s;
}
},
SEQUENCE("\\d", 12) {
@Override
void fill ( Account a, String s ) {
a.seqNumber = s;
}
},
TYPE_CODE("\\d", 2) {
@Override
void fill ( Account a, String s ) {
a.typeCode = s;
}
};
// The type string in the regex.
final String type;
// How many characters.
final int count;
AccountField(String type, int count) {
this.type = type;
this.count = count;
}
// Each field can fill its part in the Account.
abstract void fill ( Account a, String s );
// My pattern.
static Pattern pattern = Pattern.compile(asRegex());
public static Account parse ( String record ) {
Account account = new Account ();
// Fire off the matcher with the regex and put each field in the Account object.
Matcher matcher = pattern.matcher(record);
for ( AccountField f : AccountField.values() ) {
f.fill(account, matcher.group(f.ordinal() + 1));
}
return account;
}
public static String format ( Account account ) {
StringBuilder s = new StringBuilder ();
// Roll each field of the account into the string using the correct length from the enum.
return s.toString();
}
private static String regex = null;
static String asRegex() {
// Only do this once.
if (regex == null) {
// Grow my regex from the field definitions.
StringBuilder r = new StringBuilder("^");
for (AccountField f : AccountField.values()) {
r.append("(").append(f.type);
// Special case count = 1 or 2.
switch (f.count) {
case 1:
break;
case 2:
// Just one more.
r.append(f.type);
break;
default:
// More than that shoudl use the {} notation.
r.append("{").append(f.count).append("}");
break;
}
r.append(")");
}
// End of record.
r.append("$");
regex = r.toString();
}
return regex;
}
}
public static class Account {
String bankId;
String accountID;
String companyName;
String month;
String day;
String year;
String seqNumber;
String typeCode;
}
}
注意每个如何enum
封装每个领域的本质。类型、字符数以及它在Account
对象中的位置。