/// <summary> /// Получение вопросительного слова из подпредложения /// </summary> /// <param name="subSentence">подпредложение</param> /// <returns>вопросительное слово</returns> private Entity GetQuestionWord(SubSentence subSentence) { #region [.defense.] if (subSentence == null) { throw new ArgumentNullException("subSentence"); } #endregion Entity result = null; UnitTextBase unit = subSentence.Units.FirstOrDefault(_ => !_.IsEmptyText()); if ((unit != null) && unit.IsEntity) { Entity entity = (Entity)unit; if (entity.IsType(EntityType.Pretext)) { unit = unit.GetNonEmptyNext(); if (unit.IsEntity) { entity = (Entity)unit; } else { entity = null; } } if ((entity != null) && IsQuestionWord(entity)) { result = entity; } } return(result); }
/// <summary> /// Проверка, что заданная сущность - дочернее неопределенное местоимение /// </summary> /// <param name="entity">сущность</param> /// <returns>результат проверки</returns> private bool IsChildIndefinitePronoun(Entity entity) { UnitTextBase next = entity.GetNonEmptyNext(); return(entity.IsType(EntityType.Pronoun) && DictionaryResource.IsIndefinitePronoun(entity.Text) && (next != null) && (next.UnitTextType == UnitTextType.ENTITY)); }
/// <summary> /// Создание подпредложения, если необходимо /// </summary> /// <param name="builder">текст</param> /// <param name="collection">коллекция подпредложений</param> /// <param name="begin">начало интервала юнитов</param> /// <param name="end">конец интервала юнитов</param> /// <param name="isFullSentence">флаг, что текст - это все предложение</param> private void AnalyzeText(string text, List <SubSentence> collection, UnitTextBase begin, UnitTextBase end, bool isFullSentence) { if (IsSubSentence(text, isFullSentence, end == null)) { collection.Add(CreateSubSentence(begin, end)); } }
/// <summary> /// Создание подпредложения /// </summary> /// <param name="begin">начало интервала юнитов</param> /// <param name="end">конец интервала юнитов</param> /// <returns>подпредложение</returns> private SubSentence CreateSubSentence(UnitTextBase begin, UnitTextBase end) { SubSentence result = new SubSentence(SubSentenceType, begin.PositionInfo.Start); result.SetSubSentenceUnits(begin, end); return(result); }
/// <summary> /// Выделение подпредложений в заданном /// </summary> /// <param name="subSentence">подпредложение</param> /// <returns>список выделенных подпредложений</returns> protected List <SubSentence> SelectSubSentencesByContent(SubSentence subSentence) { List <SubSentence> result = new List <SubSentence>(); UnitTextBase first = null; StringBuilder builder = new StringBuilder(); foreach (UnitTextBase unit in subSentence.Units) { if (first == null) { first = unit; } if (IsSeparator(unit)) { AnalyzeText(builder.ToString(), result, first, unit.Next, false); first = unit; builder.Clear(); continue; } builder.Append(unit.Text); } AnalyzeText(builder.ToString(), result, first, null, first == subSentence.Units.First()); return(result); }
/// <summary> /// Добавление в заданную коллекию юнитов левой границы союза /// </summary> /// <param name="unitCollection">коллекция юнитов</param> /// <param name="unit">юнит, в котором начинается союз</param> /// <param name="startPosition">начальная позиция в тексте юнита</param> /// <returns>позиция в тексте юнита, с которой идет союз</returns> public int AddLeftConjunctionBorder(List <UnitTextBase> unitCollection, UnitTextBase unit, int startPosition) { int conjunctionStartPosition = Conjunction.StartPosition - unit.PositionInfo.Start; unitCollection.Add(unit.CreateUnmarkedText(startPosition, conjunctionStartPosition)); return(conjunctionStartPosition); }
/// <summary> /// Добавление союза в текущее подпредложение /// </summary> /// <param name="conjunction">союз</param> public void AddConjunctionToCurrent(Entity conjunction) { if (DictionaryResource.IsHomogeneousConjunction(conjunction.Text)) { return; } UnitTextBase previous = conjunction.GetNonEmptyPrevious(); if ((previous != null) && previous.IsSeparator(TireForms) && (CurrentSubSentence.StartUnit != previous)) { CreateNewSubSentence(previous.Previous); } if (CurrentSubSentence.IsContainConjunction) { if (previous.IsEntity && IsConjunction((Entity)previous)) { CreateNewSubSentence(previous); } else { return; } } if (CurrentType != SubSentenceType.DanglingParticiple) { CurrentSubSentence.IsContainConjunction = true; CurrentSubSentence.SubSentence.Type = ((ConjunctionEntityInfo)conjunction.EntityInfo).ConjunctionType; } }
/// <summary> /// Создание неразмеченного текста из заданного юнита /// </summary> /// <param name="text">юнит</param> /// <param name="startPosition">начало неразмеченного текста</param> /// <param name="endPosition">конец неразмеченного текста</param> /// <returns>неразмеченный текст</returns> public static UnmarkedText CreateUnmarkedText(this UnitTextBase unit, int startPosition, int endPosition) { return(new UnmarkedText ( unit.Text.Substring(startPosition, endPosition - startPosition), unit.PositionInfo.Start + startPosition )); }
public override bool IsAvailable(UnitTextBase unit) { if (unit.IsPretext()) { return(unit.Text.IsSameValue(ref _pretext)); } return(true); }
/// <summary> /// Парсинг заданного юнита по указанной позиции /// </summary> /// <param name="unit">юнит</param> /// <param name="splitPosition">позиция</param> /// <returns>пара юнитов</returns> public static Tuple <UnitTextBase, UnitTextBase> SplitUnit(this UnitTextBase unit, int splitPosition) { var units = unit.SplitUnit(new TextPart() { Start = splitPosition, End = splitPosition }); return(new Tuple <UnitTextBase, UnitTextBase>(units[0], units[1])); }
/// <summary> /// Проверка, что юнит является одним из заданных разделителей /// </summary> /// <param name="unit">юнит</param> /// <param name="separators">коллекция разделителей</param> /// <returns>результат проверки</returns> public static bool IsSeparator(this UnitTextBase unit, params string[] separators) { if (unit != null) { string text = unit.Text.Trim(); return(separators.Any(_ => _ == text)); } return(false); }
/// <summary> /// Задание юнитам нового родительского подпредложения /// </summary> /// <param name="subSentence">родительское подпредложение</param> /// <param name="begin">начало интервала юнитов</param> /// <param name="end">конец интервала юнитов</param> public static void SetSubSentenceUnits(this SubSentence subSentence, UnitTextBase begin, UnitTextBase end) { UnitTextBase current = begin; while (current != end) { current.ParentObject = subSentence; current = current.Next; } }
/// <summary> /// Выбор для юнита коллекции трансформации /// </summary> /// <param name="unit">юнит</param> /// <param name="unitsForTransform">коллекция юнитов для трансформации</param> /// <param name="noTransformdUnits">коллекция нетранфсормируемых юнитов</param> private void ChooseUnitTransformCollection(UnitTextBase unit, List <UnitTextBase> unitsForTransform, List <UnitTextBase> noTransformdUnits) { if (IsTransformAvailableUnit(unit, unitsForTransform)) { unitsForTransform.Add(unit); } else { noTransformdUnits.Add(unit); } }
/// <summary> /// Разрешение аббревиатуры /// </summary> /// <param name="abbreviation">аббревиатура</param> /// <param name="possibleAbbreviationSource">потенциальная расшифровка аббревиатуры</param> private void Resolve(Entity abbreviation, UnitTextBase possibleAbbreviationSource) { if ((abbreviation == null) || (possibleAbbreviationSource == null) || !possibleAbbreviationSource.IsEntity) { return; } string[] words = possibleAbbreviationSource.Text.Split(' ', '-'); if (!IsOnlySimpleWords(words)) { return; } char[] firstLetters = words.Select(_ => _[0]).ToArray(); int maxLevenshteinDistance = GetMaximumLevenshteinDistance(abbreviation.Value); var source = (Entity)possibleAbbreviationSource; if ((firstLetters.Length >= abbreviation.Value.Length) && IsSameLetter(firstLetters[0], abbreviation.Value[0])) { int abbreviationIndex = 1; int deleteOperationCount = 0; for (int i = 1; i < firstLetters.Length; ++i) { if ((abbreviationIndex < abbreviation.Value.Length) && IsSameLetter(firstLetters[i], abbreviation.Value[abbreviationIndex])) { ++abbreviationIndex; while ((abbreviationIndex < abbreviation.Value.Length) && (abbreviation.Value[abbreviationIndex] == ' ')) { ++abbreviationIndex; } deleteOperationCount = 0; } else { ++deleteOperationCount; --maxLevenshteinDistance; } if ((deleteOperationCount > MaximumDeleteOperationsCount) || (maxLevenshteinDistance == 0)) { break; } } if ((abbreviationIndex >= abbreviation.Value.Length) && (deleteOperationCount <= MaximumDeleteOperationsCount) && (maxLevenshteinDistance > 0)) /// удалось разрешить аббревиатуру { ((NamedEntityInfoBase)abbreviation.EntityInfo).Name = source.Value; return; } } Resolve(abbreviation, source.Children.FirstOrDefault(_ => _.PositionInfo.End == source.PositionInfo.End)); }
protected override bool IsTransformAvailableUnit(UnitTextBase unit, IList <UnitTextBase> sequence) { bool isVerbOrDeepr = false; bool isAdverb = false; if (unit.IsEntity) { Entity entity = (Entity)unit; isVerbOrDeepr = entity.IsType(EntityType.Verb) || entity.IsType(EntityType.Infinitive) || entity.IsType(EntityType.Deepr); isAdverb = entity.IsType(EntityType.Adverb); } return(isVerbOrDeepr || (sequence.Any() && (isAdverb || unit.IsEmptyText()))); }
/// <summary> /// Добавление в заданную коллекцию юнитов союза и очистка внутреннего состояния /// </summary> /// <param name="unitCollection">коллекция юнитов</param> /// <param name="unit">>юнит, в котором заканчивается союз</param> /// <param name="startPosition">начальная позиция в тексте юнита</param> /// <returns>позиция в тексте юнита, где закончился союз</returns> public int AddAndClearConjunction(List <UnitTextBase> unitCollection, UnitTextBase unit, int startPosition) { int endPosiiton = Conjunction.EndPosition - unit.PositionInfo.Start; _conjunctionValue.Append(unit.CreateUnmarkedText(startPosition, endPosiiton).Text); var conjunctionEntity = CreateNewConjunctionEntity(_conjunctionValue.ToString(), Conjunction, unit); unitCollection.Add(conjunctionEntity); Clear(); return(endPosiiton); }
private void InsertIntroductory(SubSentence introductory, UnitTextBase unit) { #region [.defense.] if (introductory.Type != SubSentenceType.Introductory) { throw new ArgumentException("subSentence isn't Introductory"); } #endregion if ((_hierarchy.CurrentSubSentence != null) && (_hierarchy.CurrentType == SubSentenceType.Participial)) { _hierarchy.CreateNewSubSentence(unit, true); } }
/// <summary> /// Проверка, что заданный юнит является разделителем подпредложений /// </summary> /// <param name="unit">юнит</param> /// <returns>результат проверки</returns> private bool IsSubSentenceSeparator(UnitTextBase unit) { if (unit.IsSeparator(c_subSentenceSeparators)) { UnitTextBase previous = unit.GetNonEmptyPrevious(); UnitTextBase next = unit.GetNonEmptyNext(); if (IsNumericWithoutSeparator(previous, unit.Text) && IsNumericWithoutSeparator(next, unit.Text)) { return(false); } return(true); } return(false); }
/// <summary> /// Проверка, что между двумя юнитами есть однородный союз /// </summary> /// <param name="begin">начало интервала</param> /// <param name="end">конец интервала</param> /// <returns>результат проверки</returns> private bool IsHomogeneousConjunctionBetween(UnitTextBase begin, UnitTextBase end) { UnitTextBase current = begin; while ((current != null) && (current != end)) { if (DictionaryResource.IsHomogeneousConjunction(current.Text)) { return(true); } current = current.GetNonEmptyNext(); } return(false); }
/// <summary> /// Получение следующего юнита с текстом /// </summary> /// <param name="unit">текущий юнит</param> /// <returns>следующий юнит с текстом</returns> public static UnitTextBase GetNonEmptyNext(this UnitTextBase unit) { UnitTextBase result = unit.Next; while (true) { if ((result == null) || !result.IsEmptyText()) { break; } result = result.Next; } return(result); }
/// <summary> /// Получение коллекции раздителей в заданном юните /// </summary> /// <param name="unit">юнит</param> /// <returns>коллекция разделителей</returns> private TextPart[] GetUnitSeparators(UnitTextBase unit) { List <TextPart> result = new List <TextPart>(); int wordPosition = 0; int separatorPosition = -1; bool isLetter = false; foreach (var word in unit.Text.Split(' ')) { int symbolPosition = wordPosition; bool isPreviousPoint = false; foreach (var symbol in word) { bool isPoint = symbol == '.'; if (!(isPoint && isPreviousPoint)) { if (!isLetter && (separatorPosition >= 0)) { result.Add(new TextPart() { Start = separatorPosition, End = symbolPosition }); separatorPosition = -1; } isPreviousPoint = isPoint; if (Char.IsLetterOrDigit(symbol) || (symbol == '-')) { isLetter = true; } else { isLetter = false; separatorPosition = symbolPosition; } } ++symbolPosition; } if (separatorPosition >= 0) { result.Add(new TextPart() { Start = separatorPosition, End = wordPosition + word.Length }); separatorPosition = -1; } wordPosition += word.Length + 1; } return(result.ToArray()); }
/// <summary> /// Добавление в заданную коллекцию юнитов неразмеченной части юнита /// </summary> /// <param name="unitCollection">коллекция юнитов</param> /// <param name="unit">юнит, часть которого добавляется в коллекцию</param> /// <param name="startPosition">начальная позиция, с которой надо добавить неразмеченную часть</param> private void AddUnmarkedPart(List <UnitTextBase> unitCollection, UnitTextBase unit, int startPosition) { if (startPosition == 0) { unitCollection.Add(unit); } else if (startPosition < unit.Text.Length) { if (unit.IsEntity) { throw new ArgumentException("unit is Entity"); } unitCollection.Add(unit.CreateUnmarkedText(startPosition, unit.Text.Length)); } }
/// <summary> /// Выделение отдельных текстовых элементов из заданного юнита /// </summary> /// <param name="unit">юнит</param> /// <returns>список отдельных текстовых элементов</returns> public static List <TextPart> SelectIndividualTextItems(UnitTextBase unit) { List <TextPart> result = new List <TextPart>(); foreach (Match match in _individualTextItemRegex.Matches(unit.Text.ToLower())) { if (IsPossibleNearSymbols(unit.Text, match)) { result.Add(new TextPart() { Start = match.Index, End = match.Index + match.Length }); } } return(result); }
/// <summary> /// Получение следующего юнита, который стоит рядом с пропуском юнитов без текста /// </summary> /// <param name="startUnit">юнит, с которого начинается поиск</param> /// <returns>юнит</returns> private UnitTextBase GetNextNearUnitSkipEmpty(UnitTextBase startUnit) { UnitTextBase result = startUnit; UnitTextBase next = result.Next; while (true) { if ((next == null) || !next.IsEmptyText() || (next.PositionInfo.Start != result.PositionInfo.End)) { break; } result = next; next = next.Next; } return(result); }
/// <summary> /// Создание нового подпредложения /// </summary> /// <param name="last">последний юнит текущего подпредложения</param> public void CreateNewSubSentence(UnitTextBase last, bool isStrongPosition = false) { var separateUnit = isStrongPosition ? GetNextNearUnitSkipEmpty(last) : last.GetNonEmptyNext(); CurrentSubSentence.SubSentence.SetSubSentenceUnits(CurrentSubSentence.StartUnit, separateUnit); _subSentenceInfoList.Add(CurrentSubSentence); if (separateUnit != null) { CurrentSubSentence = new SubSentenceInfo(separateUnit, separateUnit.PositionInfo.Start); } else { CurrentSubSentence = null; } }
/// <summary> /// Парсинг заданного юнита по указанным разделителям /// </summary> /// <param name="unit">юнит</param> /// <param name="separators">коллекция разделителей</param> /// <returns>коллекция юнитов</returns> public static List <UnitTextBase> SplitUnit(this UnitTextBase unit, params TextPart[] separators) { List <UnitTextBase> result = new List <UnitTextBase>(); int currentTextPosition = 0; foreach (var unitSeparator in separators) { result.Add(unit.CreateUnmarkedText(currentTextPosition, unitSeparator.Start)); if (unitSeparator.Start != unitSeparator.End) { result.Add(unit.CreateUnmarkedText(unitSeparator.Start, unitSeparator.End)); } currentTextPosition = unitSeparator.End; } result.Add(unit.CreateUnmarkedText(currentTextPosition, unit.Text.Length)); return(result); }
/// <summary> /// Получение коллекции раздителей в заданном юните /// </summary> /// <param name="unit">юнит</param> /// <returns>коллекция разделителей</returns> private TextPart[] GetUnitSeparators(UnitTextBase unit) { var separators = _separators.Matches(unit.Text); List <TextPart> result = new List <TextPart>(separators.Count); foreach (Match separator in separators) { if (IsCorrectSeparator(unit.Text, separator.Index, separator.Value)) { result.Add(new TextPart() { Start = separator.Index, End = separator.Index + separator.Length }); } } return(result.ToArray()); }
protected override bool IsTransformAvailableUnit(UnitTextBase unit, IList <UnitTextBase> sequence) { if (unit == null) { throw new ArgumentNullException(); } if ((unit.UnitTextType == UnitTextType.U) || (unit.UnitTextType == UnitTextType.CET)) { return(true); } else if (unit.UnitTextType == UnitTextType.ENTITY) { Entity entity = (Entity)unit; return(entity.IsType(EntityType.Pronoun) || entity.IsType(EntityType.Adverb)); } return(false); }
/// <summary> /// Добавление юнита в цепочку /// </summary> /// <param name="unit">юнит</param> /// <param name="part">часть цепочки до первой встреченной сущности</param> /// <returns>флаг допустимости юнита для цепочки</returns> private bool AddUnit(UnitTextBase unit, List <UnitTextBase> part) { bool result = true; if (unit.UnitTextType == UnitTextType.ENTITY) { Entity entity = (Entity)unit; if (_format.IsHomogeneousItem(entity)) { result = AddEntity(entity, part); part.Clear(); } else { part.Add(unit); } } else { if (DictionaryResource.IsHomogeneousConjunction(unit.Text)) { result = unit.Text.IsSameValue(ref _conjunction); } else if (DictionaryResource.IsNegotiationParticle(unit.Text)) { result = unit.Text.IsSameValue(ref _negotiationParticle); } else if (DictionaryResource.IsOtherEnumeration(unit.Text)) { _units.AddRange(part); part.Clear(); result = false; } else { result = _format.IsAvailable(unit); if (unit.IsPretext()) { _pretext = unit; } } part.Add(unit); } return(result); }
/// <summary> /// Проверка, что текущее подпредложение должно быть частью предыдущего подпредложения /// </summary> /// <param name="previous">предыдущее подпредложение</param> /// <param name="lastAdded">последнее добавленное подпредложение</param> /// <returns>результат проверки</returns> private bool IsCurrentPartOfPrevious(SubSentenceInfo previous, SubSentenceInfo lastAdded) { if ((previous != null) && !CurrentSubSentence.IsExistSubject()) { bool isPossiblePart = true; if (previous == lastAdded) { UnitTextBase firstUnit = CurrentSubSentence.SubSentence.Units.FirstOrDefault(_ => !_.IsEmptyText()); if ((firstUnit != null) && !DictionaryResource.IsHomogeneousConjunction(firstUnit.Text)) /// подпредложения не будут соединены { isPossiblePart = false; UnitTextBase secondUnit = firstUnit.GetNonEmptyNext(); if (IsAnyType(previous.SubSentence, SubSentenceType.Subordinate) && !(CurrentSubSentence.IsContainConjunction || (firstUnit.IsSeparator(",") && (secondUnit != null) && DictionaryResource.IsHomogeneousConjunction(secondUnit.Text)))) /// не пытаемся восстановить подлежащее { return(false); } } } if (IsAnyType(previous.SubSentence, SubSentenceType.Default, SubSentenceType.Subordinate)) { if (IsCurrentSubject(previous.SubSentence.Subject)) { if (CurrentSubSentence.IsContainConjunction || (CurrentSubSentence.IsExistVerb() && previous.IsExistVerb())) { CurrentSubSentence.SubSentence.set_SubjectSubSentence(previous.SubSentence); } else { return(isPossiblePart); } } } else if (!CurrentSubSentence.IsContainConjunction) { return(isPossiblePart && IsCurrentPartOfPrevious(previous)); } } return(false); }