/// ------------------------------------------------------------------------------------ /// <summary> /// Parses the given string representing the reference range. /// </summary> /// <param name="sRefRng">The string representing the reference range.</param> /// <param name="bcvRefStart">The BCV ref start.</param> /// <param name="bcvRefEnd">The BCV ref end.</param> /// <param name="fAllowDifferentBooks">if set to <c>true</c> range is allowed to span books.</param> /// <returns> /// <c>true</c> if successfully parsed; <c>false</c> otherwise /// </returns> /// ------------------------------------------------------------------------------------ public static bool ParseRefRange(string sRefRng, ref BCVRef bcvRefStart, ref BCVRef bcvRefEnd, bool fAllowDifferentBooks) { if (string.IsNullOrEmpty(sRefRng)) return false; sRefRng = sRefRng.Trim(); string[] pieces = sRefRng.Split(new [] { '-' }, StringSplitOptions.RemoveEmptyEntries); if (pieces.Length > 2 || pieces.Length == 0) return false; string sFirstRef = pieces[0]; int bbcccvvvStart = bcvRefStart.BBCCCVVV; int intVal; if (Int32.TryParse(sFirstRef, out intVal)) { if (intVal > 176) { bcvRefStart.BBCCCVVV = intVal; if (!bcvRefStart.Valid) { bcvRefStart.BBCCCVVV = bbcccvvvStart; return false; } } else { if (bcvRefStart.Book != bcvRefEnd.Book || bcvRefStart.Chapter != bcvRefEnd.Chapter) return false; bcvRefStart.Verse = intVal; } } else { // have to check *second* character because first character in a book code // can be a number; e.g. 2JN if (sFirstRef.Length < 3 || !Char.IsLetter(sFirstRef[1])) { if (bcvRefStart.Book != bcvRefEnd.Book) return false; sFirstRef = NumberToBookCode(bcvRefStart.Book) + " " + sFirstRef; } bcvRefStart.Parse(sFirstRef); if (!bcvRefStart.Valid) { bcvRefStart.BBCCCVVV = bbcccvvvStart; return false; } } if (pieces.Length == 1) { bcvRefEnd.BBCCCVVV = bcvRefStart.BBCCCVVV; return true; } string sEndRef = pieces[1]; int bbcccvvvEnd = bcvRefEnd.BBCCCVVV; // The following handles the simple case of a verse number AND the more complex case of a verse // number followed by a sub-verse segment letter. if (Int32.TryParse(sEndRef, out intVal) || (sEndRef.Length >= 2 && sEndRef.Length <= 4 && Char.IsLetter(sEndRef[sEndRef.Length - 1]) && Int32.TryParse(sEndRef.Remove(sEndRef.Length - 1), out intVal))) { if (intVal > 176) { bcvRefEnd.BBCCCVVV = intVal; if (!bcvRefEnd.Valid) { bcvRefStart.BBCCCVVV = bbcccvvvStart; bcvRefEnd.BBCCCVVV = bbcccvvvEnd; return false; } } else { bcvRefEnd.BBCCCVVV = bcvRefStart.BBCCCVVV; bcvRefEnd.Verse = intVal; } } else { if (sEndRef.Length < 3 || !Char.IsLetter(sEndRef[1])) sEndRef = NumberToBookCode(bcvRefStart.Book) + " " + sEndRef; bcvRefEnd.Parse(sEndRef); if (!bcvRefEnd.Valid || bcvRefStart > bcvRefEnd || (bcvRefStart.Book != bcvRefEnd.Book && !fAllowDifferentBooks)) { bcvRefStart.BBCCCVVV = bbcccvvvStart; bcvRefEnd.BBCCCVVV = bbcccvvvEnd; return false; } } return true; }
public void ParseTest() { BCVRef bcvRef = new BCVRef(); // Note: Don't break into individual unit tests because this test also makes sure // that the results of a previous parse don't have unintended consequences for a // subsequent parse. // Test a normal reference bcvRef.Parse("EXO 9:32"); Assert.AreEqual(2, bcvRef.Book); Assert.AreEqual(9, bcvRef.Chapter); Assert.AreEqual(32, bcvRef.Verse); // Test a bogus book bcvRef.Parse("GYQ 8:12"); Assert.AreEqual(0, bcvRef.Book); Assert.AreEqual(9, bcvRef.Chapter); Assert.AreEqual(32, bcvRef.Verse); // Test large chapter and verse numbers bcvRef.Parse("MAT 1000:2500"); Assert.AreEqual(40, bcvRef.Book); Assert.AreEqual(1000, bcvRef.Chapter); Assert.AreEqual(2500, bcvRef.Verse); // Test no chapter or verse number bcvRef.Parse("REV"); Assert.AreEqual(66, bcvRef.Book); Assert.AreEqual(1, bcvRef.Chapter); Assert.AreEqual(1, bcvRef.Verse); // Test empty string - should not crash bcvRef.Parse(""); Assert.AreEqual(0, bcvRef.Book); Assert.AreEqual(1, bcvRef.Chapter); Assert.AreEqual(1, bcvRef.Verse); // Test no verse number bcvRef.Parse("LUK 5"); Assert.AreEqual(42, bcvRef.Book); Assert.AreEqual(5, bcvRef.Chapter); Assert.AreEqual(1, bcvRef.Verse); // Test invalid format bcvRef.Parse("ROM 5!3@4"); Assert.AreEqual(0, bcvRef.Book); Assert.AreEqual(5, bcvRef.Chapter); Assert.AreEqual(3, bcvRef.Verse); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Parses the given string representing the reference range. /// </summary> /// <param name="sRefRng">The string representing the reference range.</param> /// <param name="bcvRefStart">The start reference (passed by ref because we use it to /// infer any components of the reference that are misisng in sRefRng).</param> /// <param name="bcvRefEnd">The end reference.</param> /// <param name="versification">The versification.</param> /// <returns> /// <c>true</c> if successfully parsed; <c>false</c> otherwise /// </returns> /// ------------------------------------------------------------------------------------ public static bool ParseRefRange(string sRefRng, ref BCVRef bcvRefStart, ref BCVRef bcvRefEnd, ScrVers versification) { if (string.IsNullOrEmpty(sRefRng)) return false; if (!sRefRng.Contains("--")) return BCVRef.ParseRefRange(sRefRng, ref bcvRefStart, ref bcvRefEnd, false); sRefRng = sRefRng.Trim(); string[] pieces = sRefRng.Split(new string[] { "--" }, StringSplitOptions.RemoveEmptyEntries); if (pieces.Length != 2) return false; string sFirstRef = pieces[0]; int bbcccvvvStart = bcvRefStart.BBCCCVVV; bcvRefStart.Parse(sFirstRef); if (!bcvRefStart.Valid) { bcvRefStart.BBCCCVVV = bbcccvvvStart; return false; } string sEndRef = pieces[1]; int chapter; if (Int32.TryParse(sEndRef, out chapter)) { ScrReference scrRefEnd = new ScrReference(bcvRefStart.Book, chapter, 1, versification); scrRefEnd.Verse = scrRefEnd.LastVerse; bcvRefEnd.BBCCCVVV = scrRefEnd.BBCCCVVV; return true; } return false; }