using CloudBuilder.AI.Entity; using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.DependencyInjection.Task; using CloudBuilder.Topshelf.Python; using CloudBuilder.Topshelf.Utility; using System.Text.RegularExpressions; using static System.Net.Mime.MediaTypeNames; namespace CloudBuilder.Topshelf.Task { //task:ChineseNameExtractorTask book_id:B000010 chapter_id:74 from_chapter_id:74 //task:ChineseNameExtractorTask book_id:B000010 from_chapter_id:177 to_chapter_id:200 public class ChineseNameExtractorTask : IScheduleTask { private readonly IApplicationService service; private List commonSurnames; public ChineseNameExtractorTask(IApplicationService service) { this.service = service; } public void Run(Dictionary bodyDict) { if (!bodyDict.ContainsKey("book_id")) return; string bookId = bodyDict["book_id"]; string chapterId = string.Empty; if (bodyDict.ContainsKey("chapter_id")) chapterId = bodyDict["chapter_id"]; string from_chapter_id = string.Empty; if (bodyDict.ContainsKey("from_chapter_id")) from_chapter_id = bodyDict["from_chapter_id"]; string to_chapter_id = string.Empty; if (bodyDict.ContainsKey("to_chapter_id")) to_chapter_id = bodyDict["to_chapter_id"]; PythonCommand python = new PythonCommand(service); try { Hanlp2 hanlp = new Hanlp2(python); commonSurnames = hanlp.GetSurnames(); IRepository repository = service.GetRepository>(); IRepository repositoryAiSentenceEntity = service.GetRepository>(); IRepository repositoryAiChapterPersonEntity = service.GetRepository>(); AiChapterPersonEntity[] dels = repositoryAiChapterPersonEntity.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_chapter_id))).ToArray(); if (dels != null && dels.Length > 0) repositoryAiChapterPersonEntity.DeleteNow(dels); string depRoot; List ners; List> srls; List cons = null; SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper(); AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_chapter_id))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); if (ents == null || ents.Length == 0) return; AiSentenceEntity aiSentenceEntity; string person = null; long paragraphIndex = 0; int totalLines = ents.Length; int processedLines = 0; // 已处理行数计数器 AiChapterPersonEntity aiChapterPerson; List cps = new List(); foreach (var ent in ents) { processedLines++; try { person = speakerAnalysisHelper.GetPerson(hanlp, ent.Content); paragraphIndex = ent.ParagraphId; if (!string.IsNullOrEmpty(person)) { string[] ps = person.Split(','); int orderIndex = 1; foreach (var p in ps) { if (p.Length == 1) continue; aiChapterPerson = new AiChapterPersonEntity(); aiChapterPerson.PersonName = KeepChineseCharactersOnly(p); aiChapterPerson.BookId = ent.BookId; aiChapterPerson.ChapterId = ent.ChapterId; aiChapterPerson.ParagraphIndex = ent.ParagraphId; aiChapterPerson.SentenceIndex = ent.SentenceIndex; aiChapterPerson.DialogueIndc = ent.DialogueIndc; aiChapterPerson.OrderIndex = orderIndex++; repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson); cps.Add(aiChapterPerson); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } ConsoleOutput.UpdateProgress(processedLines, totalLines); } speakerAnalysisHelper.AiChapterPersons = cps.ToArray(); speakerAnalysisHelper.CommonSurnames = commonSurnames; speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine(""); python.Dispose(); } } private string KeepChineseCharactersOnly(string input) { if (string.IsNullOrEmpty(input)) return input; // 方法1:使用正则表达式 //return Regex.Replace(input, @"[^\u4e00-\u9fff]", ""); return Regex.Replace(input, @"[^\u4e00-\u9fff\【\】]", ""); // 方法2:手动遍历(性能更好) // var sb = new StringBuilder(); // foreach (char c in input) // { // if (c >= 0x4e00 && c <= 0x9fff) // sb.Append(c); // } // return sb.ToString(); } } }