// input: "VII-VI secolo" or "III-II secolo a.C." // output: { min: 601, max: 800, label: "VII-VI secolo" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { Match m = Regex.Match(input.Trim(), GetPattern(language), options); if (!m.Success) { return(null); } string century = ""; int centuryMin = 0; int centuryMax = 0; century = m.Groups["centuryMin"].Value; centuryMin = Regex.IsMatch(century, ROMAN) ? RomanToNumber.Parse(century) : Int32.Parse(century); century = m.Groups["centuryMax"].Value; centuryMax = Regex.IsMatch(century, ROMAN) ? RomanToNumber.Parse(century) : Int32.Parse(century); EnumDatePrefix prefix1 = m.Groups["prefix1"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix1"].Value, language) : EnumDatePrefix.NONE; EnumDatePrefix prefix2 = m.Groups["prefix2"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix2"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan centuryMinSpan = getCenturyYearSpan(centuryMin, prefix1, suffix); IYearSpan centuryMaxSpan = getCenturyYearSpan(centuryMax, prefix2, suffix); return(new YearSpan(Math.Min(centuryMinSpan.min, centuryMaxSpan.min), Math.Max(centuryMinSpan.max, centuryMaxSpan.max), input, "RxFromCenturyToCentury")); }
// input: "1521", "C.1521", "C.1521 AD", "C.1521 BC" // output: { min: 1521, max: 1521, label: "C. 1521 AD" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { string pattern = GetPattern(language); Match m = Regex.Match(input.Trim(), pattern, options); if (!m.Success) { return(null); } int year = 0; int.TryParse(m.Groups["year"].Value, out year); EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; switch (suffix) { case EnumDateSuffix.BC: case EnumDateSuffix.BCE: year *= -1; break; case EnumDateSuffix.BP: year = PRESENT - year; break; } return(new YearSpan(year, input, "RxSingleYear")); }
// "THIRD CENTURY AD" public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { // using vanilla Regex: // string pattern = @"^(?<circa>C(?:irca|.)?)?\s*(?<ordinal>FIRST|SECOND|THIRD|FOURTH|FIFTH|SIXTH|SEVENTH|EIGHTH|NINTH|TENTH|ELEVENTH|TWELFTH|THIRTEENTH|FOURTEENTH|FIFTEENTH|SIXTEENTH|SEVENTEENTH|EIGHTEENTH|NINETEENTH|TWENTIETH|TWENTY FIRST)\s+(?:CENTURY|CENTURIES)\s*(?<qualifier>AD|BC|BP|na Chr)?$"; // Match m = Regex.Match(input, pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); // using VerbalExpressions: /*VerbalExpressions ve = new VerbalExpressions() * .StartOfLine() * .Maybe(oneof(en.datecircapatterns), false) * .Then(@"\s*", false) * .BeginCapture("prefix") * .Maybe(oneof(en.dateprefixpatterns), false) * .EndCapture() * .Then(@"\s*", false) * .BeginCapture("ordinal") * .Then(oneof(en.named_ordinals), false) * .EndCapture() * .Then(@"\s+century\s*", false) * .BeginCapture("qualifier") * .Maybe(oneof(en.datesuffixpatterns), false) * .EndCapture() * .EndOfLine() * .WithOptions(options); * Match m = ve.ToRegex().Match(input.Trim()); * * * if (!m.Success) return null;*/ string pattern = GetPattern(language); Match m = Regex.Match(input.Trim(), pattern, options); if (!m.Success) { return(null); } int centuryNo = m.Groups["ordinal"] != null ? (int)Lookup <EnumOrdinal> .Match(m.Groups["ordinal"].Value, language) : 0; EnumDatePrefix prefix = m.Groups["prefix"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan span = getCenturyYearSpan(centuryNo, prefix, suffix); span.label = input.Trim(); span.note = "RxOrdinalCentury"; return(span); }
// input: "1521-7" or "1521/7" or "c.1521/7 AD" or "1521-27 AD" // output: { min: 1521, max: 1527, label: "1521/7" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { Match m = Regex.Match(input.Trim(), Pattern(language), options); if (!m.Success) { return(null); } int yearMin = 0; int yearMax = 0; int.TryParse(m.Groups["yearMin"].Value, out yearMin); int.TryParse(m.Groups["yearMax"].Value, out yearMax); if (yearMax <= 9) { yearMax = yearMin - (yearMin % 10) + yearMax; } else { yearMax = yearMin - (yearMin % 100) + yearMax; } EnumDateSuffix suffix = m.Groups["suffix"] != null?DateSuffix.Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; switch (suffix) { case EnumDateSuffix.BC: yearMin *= -1; yearMax *= -1; break; case EnumDateSuffix.BP: yearMin = PRESENT - yearMin; yearMax = PRESENT - yearMax; break; } return(new YearSpan(yearMin, yearMax, input, "RxShortMaxYear")); }
// "THIRD CENTURY AD" public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { string pattern = GetPattern(language); Match m = Regex.Match(input.Trim(), pattern, options); if (!m.Success) { return(null); } int millenniumNo = m.Groups["ordinal"] != null ? (int)Lookup <EnumOrdinal> .Match(m.Groups["ordinal"].Value, language) : 0; EnumDatePrefix prefix = m.Groups["prefix"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan span = getMillenniumYearSpan(millenniumNo, prefix, suffix); span.label = input.Trim(); span.note = "RxOrdinalMillennium"; return(span); }
// input: "VII-VI secolo" or "III-II secolo a.C." // output: { min: 601, max: 800, label: "VII-VI secolo" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { Match m = Regex.Match(input.Trim(), GetPattern(language), options); if (!m.Success) { return(null); } int centuryMin = m.Groups["centuryMin"] != null ? (int)Lookup <EnumOrdinal> .Match(m.Groups["centuryMin"].Value, language) : 0; int centuryMax = m.Groups["centuryMax"] != null ? (int)Lookup <EnumOrdinal> .Match(m.Groups["centuryMax"].Value, language) : 0; EnumDatePrefix prefix1 = m.Groups["prefix1"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix1"].Value, language) : EnumDatePrefix.NONE; EnumDatePrefix prefix2 = m.Groups["prefix2"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix2"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan centuryMinSpan = getCenturyYearSpan(centuryMin, prefix1, suffix); IYearSpan centuryMaxSpan = getCenturyYearSpan(centuryMax, prefix2, suffix); return(new YearSpan(Math.Min(centuryMinSpan.min, centuryMaxSpan.min), Math.Max(centuryMinSpan.max, centuryMaxSpan.max), input, "RxFromCenturyToCenturyOrdinal")); }
//public override IYearSpan Match(string input, EnumLanguage language) public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { string pattern = GetPattern(language); Match m = Regex.Match(input.Trim(), pattern, options); // no patterns matched? if (!m.Success) { return(null); } // if we reach here we matched so get the represented year span string centuryString = m.Groups["century"].Value.Trim().ToUpper(); int centuryNo = Regex.IsMatch(centuryString, ROMAN) ? RomanToNumber.Parse(centuryString) : Int32.Parse(centuryString); EnumDatePrefix prefix = m.Groups["prefix"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan span = getCenturyYearSpan(centuryNo, prefix, suffix); span.label = input.Trim(); span.note = "RxCardinalCentury"; //this.GetType().Name; return(span); }
// input: "1st millennium" "I millennio a.C." (with language parameter) // output: { min: 1, max: 1000, label: "1st millennium" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { string pattern = Pattern(language); Match m = Regex.Match(input, pattern, options); // no patterns matched? if (!m.Success) { return(null); } // if we reach here we matched so get the represented year span string s = m.Groups["millennium"] != null ? m.Groups["millennium"].Value.Trim() : "0"; int millennium = Regex.IsMatch(s, ROMAN) ? RomanToNumber.Parse(s) : Int32.Parse(s); EnumDatePrefix prefix = m.Groups["prefix"] != null ? Lookup <EnumDatePrefix> .Match(m.Groups["prefix"].Value, language) : EnumDatePrefix.NONE; EnumDateSuffix suffix = m.Groups["suffix"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix"].Value, language) : EnumDateSuffix.NONE; IYearSpan span = getMillenniumYearSpan(millennium, prefix, suffix); span.label = input.Trim(); span.note = "RxOrdinalNumberedMillennium"; return(span); }
//public virtual string[] Patterns(EnumLanguage language) { throw new NotImplementedException(); } //public static string Pattern(EnumLanguage language) { throw new NotImplementedException(); } // public static string Pattern(EnumLanguage language, string groupname) { throw new NotImplementedException(); } // public static T Match(string input, EnumLanguage language) { throw new NotImplementedException(); } //public static bool IsMatch(string input, EnumLanguage language) { throw new NotImplementedException(); } // get span representing numbered century e.g. century 5 = { min: 401, max: 500 } // code shared by both OrdinalNamedCentury and OrdinalNumberedCentury protected internal static IYearSpan getCenturyYearSpan(int centuryNo, EnumDatePrefix prefix = EnumDatePrefix.NONE, EnumDateSuffix suffix = EnumDateSuffix.NONE) { // data cleansing of input parameters int yearMin = 0, yearMax = 0; // adjust boundaries if E/M/L qualifier is present using // (invented) boundaries: EARLY=1-40, MID=30-70, LATE=60-100 switch (suffix) { case EnumDateSuffix.BC: case EnumDateSuffix.BCE: { yearMin = (centuryNo * -100); switch (prefix) { case EnumDatePrefix.HALF1: yearMax = yearMin + 50; break; case EnumDatePrefix.HALF2: yearMin += 50; yearMax = yearMin + 49; break; case EnumDatePrefix.EARLY: yearMax = yearMin + 40; break; case EnumDatePrefix.MID: yearMin += 30; yearMax = yearMin + 40; break; case EnumDatePrefix.LATE: yearMin += 60; yearMax = yearMin + 39; break; case EnumDatePrefix.THIRD1: yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD2: yearMin += 33; yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD3: yearMin += 66; yearMax = yearMin + 33; break; case EnumDatePrefix.QUARTER1: yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER2: yearMin += 25; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER3: yearMin += 50; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER4: yearMin += 75; yearMax = yearMin + 24; break; default: // There is no year zero... yearMax = yearMin + 99; break; } break; } case EnumDateSuffix.BP: { yearMin = PRESENT - (centuryNo * 100) + 1; switch (prefix) { case EnumDatePrefix.HALF1: yearMax = yearMin + 50; break; case EnumDatePrefix.HALF2: yearMin += 50; yearMax = yearMin + 49; break; case EnumDatePrefix.EARLY: yearMax = yearMin + 40; break; case EnumDatePrefix.MID: yearMin += 30; yearMax = yearMin + 40; break; case EnumDatePrefix.LATE: yearMin += 60; yearMax = yearMin + 39; break; case EnumDatePrefix.THIRD1: yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD2: yearMin += 33; yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD3: yearMin += 66; yearMax = yearMin + 33; break; case EnumDatePrefix.QUARTER1: yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER2: yearMin += 25; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER3: yearMin += 50; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER4: yearMin += 75; yearMax = yearMin + 24; break; default: // There is no year zero... yearMax = yearMin + 99; break; } break; } default: // AD, CE or NONE { yearMin = (centuryNo * 100) - 99; switch (prefix) { case EnumDatePrefix.HALF1: yearMax = yearMin + 49; break; case EnumDatePrefix.HALF2: yearMin += 49; yearMax = yearMin + 50; break; case EnumDatePrefix.EARLY: yearMax = yearMin + 39; break; case EnumDatePrefix.MID: yearMin += 29; yearMax = yearMin + 40; break; case EnumDatePrefix.LATE: yearMin += 59; yearMax = yearMin + 40; break; case EnumDatePrefix.THIRD1: yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD2: yearMin += 33; yearMax = yearMin + 33; break; case EnumDatePrefix.THIRD3: yearMin += 66; yearMax = yearMin + 33; break; case EnumDatePrefix.QUARTER1: yearMax = yearMin + 24; break; case EnumDatePrefix.QUARTER2: yearMin += 24; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER3: yearMin += 49; yearMax = yearMin + 25; break; case EnumDatePrefix.QUARTER4: yearMin += 74; yearMax = yearMin + 25; break; default: yearMax = yearMin + 99; break; } break; } } // TODO: not currently accounting for earlymid, or midlate return(new YearSpan(yearMin, yearMax)); }
// input: "1521-1527" or "1521/1527" or "c.1521/1527 AD" or "1521-1527 AD" // output: { min: 1521, max: 1527, label: "1521-1527" } public static IYearSpan Match(string input, EnumLanguage language = EnumLanguage.NONE) { Match m = Regex.Match(input.Trim(), GetPattern(language), options); if (!m.Success) { return(null); } int yearMin = 0; int yearMax = 0; int.TryParse(m.Groups["yearMin"].Value, out yearMin); int.TryParse(m.Groups["yearMax"].Value, out yearMax); EnumDateSuffix suffix1 = m.Groups["suffix1"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix1"].Value, language) : EnumDateSuffix.NONE; EnumDateSuffix suffix2 = m.Groups["suffix2"] != null ? Lookup <EnumDateSuffix> .Match(m.Groups["suffix2"].Value, language) : EnumDateSuffix.NONE; if (suffix1 == EnumDateSuffix.NONE && suffix2 != EnumDateSuffix.NONE) { suffix1 = suffix2; } if (suffix2 == EnumDateSuffix.NONE && suffix1 != EnumDateSuffix.NONE) { suffix2 = suffix1; } // handling possible short max year here e.g. "1560-89 AD" if (yearMax < yearMin && suffix1 != EnumDateSuffix.BC) { if (yearMax <= 9) { yearMax = yearMin - (yearMin % 10) + yearMax; } else if (yearMax >= 10 && yearMax <= 99) { yearMax = yearMin - (yearMin % 100) + yearMax; } } switch (suffix1) { case EnumDateSuffix.BC: case EnumDateSuffix.BCE: yearMin *= -1; break; case EnumDateSuffix.BP: yearMin = PRESENT - yearMin; break; } switch (suffix2) { case EnumDateSuffix.BC: case EnumDateSuffix.BCE: yearMax *= -1; break; case EnumDateSuffix.BP: yearMax = PRESENT - yearMax; break; } return(new YearSpan(Math.Min(yearMin, yearMax), Math.Max(yearMin, yearMax), input, "RxFromYearToYear")); }