diff --git a/core/src/com/google/zxing/client/result/VCardResultParser.java b/core/src/com/google/zxing/client/result/VCardResultParser.java index b5493e3a4..02e1734cf 100644 --- a/core/src/com/google/zxing/client/result/VCardResultParser.java +++ b/core/src/com/google/zxing/client/result/VCardResultParser.java @@ -41,7 +41,7 @@ public final class VCardResultParser extends ResultParser { private static final Pattern VCARD_ESCAPES = Pattern.compile("\\\\([,;\\\\])"); private static final Pattern EQUALS = Pattern.compile("="); private static final Pattern SEMICOLON = Pattern.compile(";"); - private static final Pattern SEMICOLONS = Pattern.compile(";+"); + private static final Pattern UNESCAPED_SEMICOLONS = Pattern.compile("(?> names = matchVCardPrefixedField("FN", rawText, true); + List> names = matchVCardPrefixedField("FN", rawText, true, false); if (names == null) { // If no display names found, look for regular name fields and format them - names = matchVCardPrefixedField("N", rawText, true); + names = matchVCardPrefixedField("N", rawText, true, false); formatNames(names); } - List> phoneNumbers = matchVCardPrefixedField("TEL", rawText, true); - List> emails = matchVCardPrefixedField("EMAIL", rawText, true); - List note = matchSingleVCardPrefixedField("NOTE", rawText, false); - List> addresses = matchVCardPrefixedField("ADR", rawText, true); - if (addresses != null) { - for (List list : addresses) { - String adr = list.get(0); - // Semicolon separators -- just make them a newline - adr = SEMICOLONS.matcher(adr).replaceAll("\n").trim(); - list.set(0, adr); - } - } - List org = matchSingleVCardPrefixedField("ORG", rawText, true); - List birthday = matchSingleVCardPrefixedField("BDAY", rawText, true); + List> phoneNumbers = matchVCardPrefixedField("TEL", rawText, true, false); + List> emails = matchVCardPrefixedField("EMAIL", rawText, true, false); + List note = matchSingleVCardPrefixedField("NOTE", rawText, false, false); + List> addresses = matchVCardPrefixedField("ADR", rawText, true, true); + List org = matchSingleVCardPrefixedField("ORG", rawText, true, false); + List birthday = matchSingleVCardPrefixedField("BDAY", rawText, true, false); if (birthday != null && !isLikeVCardDate(birthday.get(0))) { birthday = null; } - List title = matchSingleVCardPrefixedField("TITLE", rawText, true); - List url = matchSingleVCardPrefixedField("URL", rawText, true); - List instantMessenger = matchSingleVCardPrefixedField("IMPP", rawText, true); + List title = matchSingleVCardPrefixedField("TITLE", rawText, true, false); + List url = matchSingleVCardPrefixedField("URL", rawText, true, false); + List instantMessenger = matchSingleVCardPrefixedField("IMPP", rawText, true, false); return new AddressBookParsedResult(toPrimaryValues(names), null, toPrimaryValues(phoneNumbers), @@ -97,7 +89,8 @@ public final class VCardResultParser extends ResultParser { private static List> matchVCardPrefixedField(CharSequence prefix, String rawText, - boolean trim) { + boolean trim, + boolean parseFieldDivider) { List> matches = null; int i = 0; int max = rawText.length(); @@ -172,7 +165,13 @@ public final class VCardResultParser extends ResultParser { } if (quotedPrintable) { element = decodeQuotedPrintable(element, quotedPrintableCharset); + if (parseFieldDivider) { + element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll("\n").trim(); + } } else { + if (parseFieldDivider) { + element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll("\n").trim(); + } element = CR_LF_SPACE_TAB.matcher(element).replaceAll(""); element = NEWLINE_ESCAPE.matcher(element).replaceAll("\n"); element = VCARD_ESCAPES.matcher(element).replaceAll("$1"); @@ -253,8 +252,9 @@ public final class VCardResultParser extends ResultParser { static List matchSingleVCardPrefixedField(CharSequence prefix, String rawText, - boolean trim) { - List> values = matchVCardPrefixedField(prefix, rawText, trim); + boolean trim, + boolean parseFieldDivider) { + List> values = matchVCardPrefixedField(prefix, rawText, trim, parseFieldDivider); return values == null || values.isEmpty() ? null : values.get(0); } diff --git a/core/src/com/google/zxing/client/result/VEventResultParser.java b/core/src/com/google/zxing/client/result/VEventResultParser.java index 44a01411e..821a007eb 100644 --- a/core/src/com/google/zxing/client/result/VEventResultParser.java +++ b/core/src/com/google/zxing/client/result/VEventResultParser.java @@ -74,7 +74,7 @@ public final class VEventResultParser extends ResultParser { private static String matchSingleVCardPrefixedField(CharSequence prefix, String rawText, boolean trim) { - List values = VCardResultParser.matchSingleVCardPrefixedField(prefix, rawText, trim); + List values = VCardResultParser.matchSingleVCardPrefixedField(prefix, rawText, trim, false); return values == null || values.isEmpty() ? null : values.get(0); } diff --git a/core/test/src/com/google/zxing/client/result/AddressBookParsedResultTestCase.java b/core/test/src/com/google/zxing/client/result/AddressBookParsedResultTestCase.java index d96f98754..cf29810a6 100644 --- a/core/test/src/com/google/zxing/client/result/AddressBookParsedResultTestCase.java +++ b/core/test/src/com/google/zxing/client/result/AddressBookParsedResultTestCase.java @@ -84,7 +84,7 @@ public final class AddressBookParsedResultTestCase extends Assert { "=38=38=20=4C=79=6E=62=72=6F=6F=6B=0D=0A=43=\r\n" + "=4F=20=36=39=39=\r\n" + "=39=39;;;\r\nEND:VCARD", - null, null, null, new String[] {";;88 Lynbrook\r\nCO 69999;;;"}, + null, null, null, new String[] {"88 Lynbrook\r\nCO 69999"}, null, null, null, null, null, null); }