diff --git a/src/de/schildbach/pte/MvvProvider.java b/src/de/schildbach/pte/MvvProvider.java
index 6d4399fc..fb2e0b3d 100644
--- a/src/de/schildbach/pte/MvvProvider.java
+++ b/src/de/schildbach/pte/MvvProvider.java
@@ -470,18 +470,19 @@ public class MvvProvider implements NetworkProvider
private static final Pattern P_CONNECTION_DETAILS_HEAD = Pattern.compile(".*Detailansicht.*?" //
+ "Datum:[\\xa0\\s]+\\w{2}\\.,\\s(\\d+)\\.\\s(\\w{3,4})\\.[\\xa0\\s]+(\\d{4}).*", Pattern.DOTALL);
- private static final Pattern P_CONNECTION_DETAILS_COARSE = Pattern.compile("
(.+?)
.*?"
- + "(.+?)
.*?" //
- + "(.+?)
", Pattern.DOTALL);
- static final Pattern P_CONNECTION_DETAILS_FINE = Pattern.compile(".*?(?:" //
- + "ab (\\d+:\\d+)\\s+(.*?)\\s*<.*?" //
- + "
.*?" //
+ private static final Pattern P_CONNECTION_DETAILS_COARSE = Pattern.compile("" //
+ + "\r\\x0a(.+?)
.*?" //
+ + "\r\\x0a(.+?)
.*?" //
+ + "\r\\x0a(.+?)
", Pattern.DOTALL);
+ static final Pattern P_CONNECTION_DETAILS_FINE = Pattern.compile("(?:" //
+ + "ab (\\d{1,2}:\\d{2})\\s(.*?)\\s*<.*?" // departureTime, departure
+ + "(?: .*?)?" // product
+ " | \\s*(.*?)\\s* Richtung\\s*(.*?)\\s* | .*?" //
- + "an (\\d+:\\d+)\\s+(.*?)\\s*<" //
+ + "an (\\d{1,2}:\\d{2})\\s(.*?)\\s*<" //
+ "|" //
- + "ab\\s+(.*?)\\s*<.*?" //
+ + " | ab (.*?)\\s*<.*?" // departure
+ "Fußweg[\\xa0\\s]+\\(ca\\.[\\xa0\\s]+(\\d+)[\\xa0\\s]+Minute.*?" //
- + "an\\s+(.*?)\\s*<" //
+ + " | an (.*?)\\s*<" //
+ ").*?", Pattern.DOTALL);
private static final Pattern P_CONNECTION_DETAILS_ERRORS = Pattern.compile("(session has expired)", Pattern.CASE_INSENSITIVE);
private static final String SITZENBLEIBER = "Sitzenbleiber";
@@ -502,10 +503,17 @@ public class MvvProvider implements NetworkProvider
String firstDeparture = null;
Date lastArrivalTime = null;
String lastArrival = null;
+ String oldZebra = null;
final Matcher mDetCoarse = P_CONNECTION_DETAILS_COARSE.matcher(page);
while (mDetCoarse.find())
{
+ final String zebra = mDetCoarse.group(1);
+ if (oldZebra != null && zebra.equals(oldZebra))
+ throw new IllegalArgumentException("missed row? last:" + zebra);
+ else
+ oldZebra = zebra;
+
final String set = mDetCoarse.group(2) + mDetCoarse.group(3) + mDetCoarse.group(4);
if (!set.contains(SITZENBLEIBER))
{
diff --git a/test/de/schildbach/pte/MvvProviderTest.java b/test/de/schildbach/pte/MvvProviderTest.java
index 526b3edf..51e3f768 100644
--- a/test/de/schildbach/pte/MvvProviderTest.java
+++ b/test/de/schildbach/pte/MvvProviderTest.java
@@ -17,6 +17,8 @@
package de.schildbach.pte;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import java.util.regex.Matcher;
@@ -32,66 +34,89 @@ public class MvvProviderTest
@Test
public void trip()
{
- assertFineConnectionDetails("\n" //
+ final Matcher m = assertFineConnectionDetails("" //
+ " | ab 04:27 Machern (Sachs) Gleis 2 \n" //
+ " | \n" //
- + "\n" //
+ "\n" //
+ " \n" //
+ " | \n" //
+ " | \n" //
+ "MRB 88040 Mitteldeutsche Regiobahn Richtung Leipzig Hbf | \n" //
+ " | \n" //
- + "\n" //
+ "an 04:47 Leipzig Hbf Gleis 19 | \n");
+
+ assertNotNull(m.group(1)); // departureTime
+ assertNotNull(m.group(2)); // departure
+ assertNotNull(m.group(3)); // product
}
@Test
public void trip2()
{
- assertFineConnectionDetails("\n" //
+ final Matcher m = assertFineConnectionDetails("" //
+ "ab 09:04 Hauptbahnhof Haupthalle Gleis 26 \n" //
+ " \n" //
+ " | \n" //
- + "\n" //
+ "\n" //
+ " \n" //
+ " | \n" //
+ " | \n" //
+ "RE 4006 RegionalExpress Richtung Nürnberg Hbf | \n" //
+ " | \n" //
- + "\n" //
+ "an 10:47 Nürnberg Hbf Gleis 12 | \n");
+
+ assertNotNull(m.group(1)); // departureTime
+ assertNotNull(m.group(2)); // departure
+ assertNotNull(m.group(3)); // product
}
@Test
@Ignore("deactivated because there is no time")
public void tripWithoutTime()
{
- assertFineConnectionDetails("\n" //
+ final Matcher m = assertFineConnectionDetails("" //
+ "ab Neufahrn \n" //
+ " \n" //
+ " | \n" //
- + "\n" //
+ "\n" //
+ " \n" //
+ " | \n" //
+ " | \n" //
+ "nicht umsteigen | \n" //
+ " | \n" //
- + "\n" //
+ "an Neufahrn \n" //
+ " | \n");
+
+ assertNotNull(m.group(2)); // departure
+ assertNotNull(m.group(3)); // product
+ }
+
+ @Test
+ public void tripWithoutProduct()
+ {
+ final Matcher m = assertFineConnectionDetails("" //
+ + "ab 07:46 Niederstraub. Abzw.Krottenthal \n" //
+ + " \n" //
+ + " | \n" //
+ + " | \n" //
+ + " | \n" //
+ + "MVV-Ruftaxi 5621 Richtung Taufkirchen (Vils) Busbahnhof | \n" //
+ + " | \n" //
+ + "an 07:49 Dickarting \n" //
+ + " | \n");
+
+ assertNotNull(m.group(1)); // departureTime
+ assertNotNull(m.group(2)); // departure
+ assertNull(m.group(3)); // product
}
@Test
public void footway()
{
- assertFineConnectionDetails("\n" //
+ final Matcher m = assertFineConnectionDetails("" //
+ "ab München Infanteriestraße 7 \n" //
+ " \n" //
+ " | \n" //
- + "\n" //
+ "\n" //
+ " \n" //
+ " | \n" //
@@ -100,18 +125,18 @@ public class MvvProviderTest
+ " (ca. 3 Minuten)\n" //
+ " \n" //
+ " | \n" //
- + "\n" //
+ "an Infanteriestraße Süd \n" //
+ " | \n");
+
+ assertNotNull(m.group(8)); // departure
}
@Test
public void footway2()
{
- assertFineConnectionDetails("\n" //
+ final Matcher m = assertFineConnectionDetails("" //
+ "ab Weimar Gleis 1 \n" //
+ " | \n" //
- + "\n" //
+ "\n" //
+ " \n" //
+ " | \n" //
@@ -120,14 +145,18 @@ public class MvvProviderTest
+ "(ca. 2 Minuten)\n" //
+ "\n" //
+ " | \n" //
- + "\n" //
+ "an Weimar Gleis 2 | \n");
+
+ assertNotNull(m.group(8)); // departure
}
- private void assertFineConnectionDetails(String s)
+ private Matcher assertFineConnectionDetails(String s)
{
Matcher m = MvvProvider.P_CONNECTION_DETAILS_FINE.matcher(s);
assertTrue(m.matches());
+
// ParserUtils.printGroups(m);
+
+ return m;
}
}