/// <summary> /// 编码内容解析 /// </summary> /// <param name="pnrContentStr">Pnr内容</param> /// <param name="isIgnoreError">是否忽略解析错误</param> /// <returns>结果</returns> public MPnrContent PnrAnalyse(string pnrContentStr, bool isIgnoreError) { MPnrContent pnrModel = new MPnrContent(); pnrModel.PNRContentStr = pnrContentStr; /***********************************编码状态******************************************/ PNRStatus status = PNRStatus.Normal; if (Regex.IsMatch(pnrContentStr, @"NO PNR|NO NAME|FLIGHT NUMBER|PNR不存在")) { status = PNRStatus.NoPNR; } ////已取消 if (Regex.IsMatch(pnrContentStr, @"CANCELLED")) { status = PNRStatus.Cancelled; } ////已出票 if (Regex.IsMatch(pnrContentStr, @"((TN/)|(\*\*ELECTRONIC TICKET PNR\*\*)|(SSR TKNE)|(AND PRINTED)|(ETICKET PNR)|(OSI 1E \w{2}ET TN))")) { status = PNRStatus.Outed; } pnrModel.Status = status; /***********************************大编码******************************************/ ////大编码:14.RMK CA/LL8RC ////Regex reg = new Regex(@"(?:\d{1,2}\.RMK CA/)(\w{5})", RegexOptions.IgnoreCase); ////PNR升位,DLF测试新加,大编码中不知道有无空格,是否也升级到6位,现在是默认支持5到6位,包括空格 Regex reg = new Regex(@"(?:\d{1,2}\.RMK CA/)(\w{5,6})", RegexOptions.IgnoreCase); Match matBigPnr = reg.Match(pnrContentStr); if (matBigPnr.Success && matBigPnr.Groups.Count >= 2) { pnrModel.BigPnr = matBigPnr.Groups[1].Value; } /***********************************office号******************************************/ Match matOffice = Regex.Match(pnrContentStr, @"(?:\d{1,2}\.)(?<OFFICE>[A-Z]{3}\d{3})", RegexOptions.RightToLeft); if (matOffice.Success) { pnrModel.OfficeCode = matOffice.Groups["OFFICE"].Value; } else { // 20130417 C系统内容如果末尾项没有Office号则再从时间项中取Office // eg. 6.TL/2330/08APR/NKG151 matOffice = Regex.Match(pnrContentStr, @"\d{1,2}\.TL\/\d{4}\/\d{2}[A-Z]{3}\/(?<OFFICE>[A-Z]{3}\d{3})"); if (matOffice.Success) { pnrModel.OfficeCode = matOffice.Groups["OFFICE"].Value; } } /**********************************SSR FOID 项数量*****************************************/ reg = new Regex(@"\d{1,2}\.(SSR FOID|SSR INFT)"); MatchCollection matsSSR = reg.Matches(pnrContentStr); pnrModel.SSRFOIDCount = matsSSR.Count; /***************************是否为团队票,团队票以"0."开头**********************************/ if (Regex.IsMatch(pnrContentStr, @"^\s*0\.")) { pnrModel.IsTeam = true; } /***************************解析乘客**********************************/ pnrModel.Passengers.AddRange(GetAdultPassenger(pnrModel, pnrContentStr, isIgnoreError)); // 处理婴儿 pnrModel.Passengers.AddRange(this.GetBabys(pnrContentStr)); /***************************解析航段舱位**********************************/ pnrModel.Seats.AddRange(this.GetSeats(pnrContentStr)); /***************************解析价格**********************************/ pnrModel.Pice.AddRange(this.AnalysePrice(pnrContentStr)); return(pnrModel); }
/// <summary> /// 获得成人乘客 /// </summary> /// <param name="pnrModel">pnrModel</param> /// <param name="pnrContentStr">pnrContentStr</param> /// <param name="isIgnoreError">是否忽略解析错误</param> /// <returns>乘客集合</returns> public List <MPnrMPassenger> GetAdultPassenger(MPnrContent pnrModel, string pnrContentStr, bool isIgnoreError) { string pnrCode; List <MPnrMPassenger> passengers = new List <MPnrMPassenger>(); ////是否为团队票 PNR升位,DLF测试新加 Match isTeam = Regex.Match(pnrContentStr, @"0\.(?<YDRS>\d{1,3}).{1,20}\sNM(?<SJRS>\d{1,3}) +(?<PNR>(\w{5,6}))"); Match mat; if (isTeam.Success) { ////团队编码 Regex reg = new Regex(@"(?<NAME>(?:1\.)(?:.|\n)+?)\s+\d{1,2}\. (?:\*| |[A-Z])", RegexOptions.IgnoreCase); mat = reg.Match(pnrContentStr); ////PNR pnrCode = isTeam.Groups["PNR"].Value; if (pnrModel != null) { pnrModel.IsTeam = true; } } else { //// 散客编码PNR升位,DLF测试新加 2011-11-8 内容导入用户会把RT(PNR)这一行输入 导致编码中带有1的会被当做姓名内容匹配到 Regex reg = new Regex(@"(?<NAME>(?:1?\.|0\.)(?:.|\n)+?) (?<PNR>(\w{5,6}))(?:/[A-Z0-9]{2})?\s+\d{1,2}\. ", RegexOptions.IgnoreCase); mat = reg.Match(pnrContentStr); if (!mat.Success) { //// 解决pnr与名字之间没有空格的而导致不能匹配的问题 reg = new Regex(@"(?<NAME>(?:1?\.|0\.)(?:.|\n)+?)(?:| )(?<PNR>(\w{1,6}))(?:/[A-Z0-9]{2})?\s+\d{1,2}\. ", RegexOptions.IgnoreCase); mat = reg.Match(pnrContentStr); } pnrCode = mat.Groups["PNR"].Value.Replace(" ", string.Empty); if (Regex.IsMatch(pnrCode, "[^A-Za-z0-9]")) { System.Exception ex = new System.Exception("从PNR内容中获取乘客信息失败。"); throw ex; } ////编码换行特殊处理 if (pnrCode.Trim().Length < 6) { string nameStr = Regex.Replace(mat.Value.Trim(), "\n|\r", string.Empty); mat = reg.Match(nameStr + " ");////补空格 pnrCode = mat.Groups["PNR"].Value.Replace(" ", string.Empty); } } if (pnrModel != null) { pnrModel.Pnr = pnrCode; } if (!mat.Success && isIgnoreError == false) { System.Exception ex = new System.Exception("从PNR内容中获取乘客信息失败。"); throw ex; } ////乘客姓名 string passengerNames = Regex.Replace(mat.Groups["NAME"].Value, "\n|\r| \n| \r|\t", string.Empty).Trim(); passengerNames = passengerNames + " "; ////如果名字后面没有空格,则直接加入空格。 passengerNames = Regex.Replace( passengerNames, @"([A-Z|\u4e00-\u9fa5])(\d)", delegate(Match match) { return(match.Value.Insert(1, " ")); }); MatchCollection matches = Regex.Matches( passengerNames, @"(?:(?<NUM>\d{1,2})\.?)?(?<NAME>(?:[A-Z]{1,35}/([A-Z]| ){1,35})(?= |\d)|(?:(?:[\u2E80-\u9FFF]|[A-Z]){1,50}) )", RegexOptions.IgnoreCase); ////乘客编号 int i = 1; ////最后一个乘机人NUM int lastIndex = 0; ////乘客类型 PassengerType passengerType; ////证件类型 string credentialsType; ////结算号 string settle; ////乘客MODEL MPnrMPassenger passengerModel; ////是否有手机号 //Regex regex = new Regex(@"\d{1,2}\.OSI (?<AIRCODE>\w{2}).+(?<PHONE>\d{11})"); Regex regex = new Regex(@"\d{1,2}\.OSI (?<AIRCODE>\w{2}) CT[^\d]*(?<PHONE>\d{0,})(?:|/P\d{1,2})\s+"); MatchCollection mats = regex.Matches(pnrContentStr); string mobile = string.Empty; if (mats.Count > 0) { foreach (Match m in mats) { ////0开头被认为是座机,仍需补手机号 if (!m.Groups["PHONE"].Value.StartsWith("0") && m.Groups["PHONE"].Value.Trim().Length == 11) { mobile = m.Groups["PHONE"].Value; } else if (m.Groups["PHONE"].Value.Trim().Length == 0) { mobile = "13800000000"; //随便给一个号,客户端就会当做有手机号了 (配置有时提不出手机号) } ////获取到了正确的手机号 if (mobile.Length > 0 && !mobile.StartsWith("0")) { break; } } } else { ////2011-10-17 只要有OSI CT就算补过手机号了 regex = new Regex(@"\d{1,2}\.OSI CT"); Match mm = regex.Match(pnrContentStr); if (mm.Success) { mobile = "13800000000"; //随便给一个号,客户端就会当做有手机号了 } } foreach (Match match in matches) { if (match.Groups["NAME"].Value.Trim().Length == 0) { continue; } passengerModel = new MPnrMPassenger(); passengerModel.SequenceNO = i; ////乘客名 passengerModel.Name = this.GetName(match.Groups["NAME"].Value.Trim(), out passengerType); passengerModel.Type = passengerType; ////证件 passengerModel.CredID = this.GetCredentialsCode(pnrContentStr, passengerModel.SequenceNO, out credentialsType); //passengerModel.CardID = credentialsType; ////票号 passengerModel.TicketCode = this.GetTeckitCode(pnrContentStr, passengerModel.SequenceNO, out settle, PassengerType.成人); passengerModel.SettleCode = settle; ////手机号 passengerModel.MobileNo = mobile; ////添加乘客 passengers.Add(passengerModel); i++; int.TryParse(match.Groups["NUM"].Value, out lastIndex); } if (lastIndex != 0 && lastIndex != passengers.Count) { System.Exception ex = new System.Exception("乘机人数解析异常,解析到的人数和实际人数不一致"); throw ex; } if (passengers.Count == 0 && isIgnoreError == false) { System.Exception ex = new System.Exception("没有解析到任何乘机人"); throw ex; } return(passengers); }