Как вариант можно вшить в функцию еще работу с таблицей исключений из 2-х колонок [vba]
Код
Function Split_by_sentence(ByVal StringInp As String, Optional ByVal Patt As String = "([\.|\?|\!|\n]+(\s+)?[A-ZА-Я])", Optional ByVal Tabl) Dim i&, arr() As String If TypeName(Tabl) = "Range" Then Tabl = Tabl.Value If TypeName(Tabl) = "Error" Then Tabl = Application.Evaluate("={"" т.е."","" тЇeЇ"";"" г."","" гЇ"";"" т.д."","" тЇдЇ""}") For t = LBound(Tabl) To UBound(Tabl): StringInp = Replace(StringInp, Tabl(t, 1), Tabl(t, 2)): Next With CreateObject("Vbscript.regexp") .Pattern = Patt .Global = True If Not .test(StringInp) Then ReDim arr(0) arr(0) = StringInp Else Set Matches = .Execute(StringInp) ReDim arr(Matches.Count) For i = 0 To Matches.Count - 1 If i = 0 Then arr(i) = Left(StringInp, Matches(i).FirstIndex + Len(Matches(i).submatches(0)) - 1) Else arr(i) = Mid(StringInp, Matches(i - 1).FirstIndex + Matches(i - 1).Length - 1, Matches(i).FirstIndex - Matches(i - 1).FirstIndex - Matches(i - 1).Length + Matches(i).Length) End If For t = LBound(Tabl) To UBound(Tabl): arr(i) = Replace(arr(i), Tabl(t, 2), Tabl(t, 1)): Next arr(i) = Trim(arr(i)) Next arr(i) = Mid(StringInp, Matches(i - 1).FirstIndex + Matches(i - 1).Length - 1, 999) For t = LBound(Tabl) To UBound(Tabl): arr(i) = Replace(arr(i), Tabl(t, 2), Tabl(t, 1)): Next arr(i) = Trim(arr(i)) End If End With
If Application.Caller.Cells.Count > UBound(arr) + 1 Then ReDim Preserve arr(Application.Caller.Cells.Count) Split_by_sentence = arr End Function
Как вариант можно вшить в функцию еще работу с таблицей исключений из 2-х колонок [vba]
Код
Function Split_by_sentence(ByVal StringInp As String, Optional ByVal Patt As String = "([\.|\?|\!|\n]+(\s+)?[A-ZА-Я])", Optional ByVal Tabl) Dim i&, arr() As String If TypeName(Tabl) = "Range" Then Tabl = Tabl.Value If TypeName(Tabl) = "Error" Then Tabl = Application.Evaluate("={"" т.е."","" тЇeЇ"";"" г."","" гЇ"";"" т.д."","" тЇдЇ""}") For t = LBound(Tabl) To UBound(Tabl): StringInp = Replace(StringInp, Tabl(t, 1), Tabl(t, 2)): Next With CreateObject("Vbscript.regexp") .Pattern = Patt .Global = True If Not .test(StringInp) Then ReDim arr(0) arr(0) = StringInp Else Set Matches = .Execute(StringInp) ReDim arr(Matches.Count) For i = 0 To Matches.Count - 1 If i = 0 Then arr(i) = Left(StringInp, Matches(i).FirstIndex + Len(Matches(i).submatches(0)) - 1) Else arr(i) = Mid(StringInp, Matches(i - 1).FirstIndex + Matches(i - 1).Length - 1, Matches(i).FirstIndex - Matches(i - 1).FirstIndex - Matches(i - 1).Length + Matches(i).Length) End If For t = LBound(Tabl) To UBound(Tabl): arr(i) = Replace(arr(i), Tabl(t, 2), Tabl(t, 1)): Next arr(i) = Trim(arr(i)) Next arr(i) = Mid(StringInp, Matches(i - 1).FirstIndex + Matches(i - 1).Length - 1, 999) For t = LBound(Tabl) To UBound(Tabl): arr(i) = Replace(arr(i), Tabl(t, 2), Tabl(t, 1)): Next arr(i) = Trim(arr(i)) End If End With
If Application.Caller.Cells.Count > UBound(arr) + 1 Then ReDim Preserve arr(Application.Caller.Cells.Count) Split_by_sentence = arr End Function
как изменить количество колонок, на которые делятся предложения? Сейчас на 3 колонки делятся, в остальных написано "Н/Д"
Тю! А у меня что-то сложилось устойчивое впечатление, что надо именно по 3-м разбить: первое предложение, второе и остальной текст. "А оно вона чо, Михалыч!" (с) Ну и ладно, так ещё и проще получается.
[vba]
Код
Function splitTo3parts(ByVal strSource) Dim objRegExp As Object 'RegExp Dim colMatches As Object 'MatchCollection Dim aMatch As Object 'Match Dim sep As String
sep = vbTab
Set objRegExp = CreateObject("VBScript.RegExp") objRegExp.Global = True
'перенос строки как окончание предложения, чтобы точно так же, как предложение с точкой objRegExp.Pattern = "[^.?!]" & vbLf 'случай Alt+Enter в ячейке strSource = replaceEOL(objRegExp, strSource)
'а также неразрывного пробела - символа с кодом 160 strSource = Replace(strSource, Chr(160), " ")
'дополнительно чистим ПЕЧСИМВ (вдруг что-то еще осталось) 'и удаляем лишние пробелы With WorksheetFunction strSource = .Clean(strSource) strSource = .Trim(strSource) 'именно Trim табличной функцией End With 'здесь между символами остался максимум ОДИН пробел
'временно заменяем исключения - типа города г. и т.е., чтобы не мешались точками 'а также сюда добавим другие, если еще найдутся strSource = Replace(strSource, " г. ", " г_| ", , , vbBinaryCompare) 'заменяем только строчную "г." strSource = Replace(strSource, " т.е. ", " т_|е_| ")
objRegExp.Pattern = "[.?!]\s[A-ZА-Я0-9""]" 'добавил возможность начала предложения с цифры и двойной кавычки
Set colMatches = objRegExp.Execute(strSource)
For Each aMatch In colMatches 'меняем все совпадения (а не только первые два, как раньше) Mid(strSource, aMatch.FirstIndex + 2) = sep Next
'восстанавливаем исключения - типа города и т.е. strSource = Replace(strSource, "г_|", "г.") strSource = Replace(strSource, "т_|е_|", "т.е.")
'с защитой от #Н/Д и 0 на 100 ячеек (предложений), начиная со 101-й ячейки пойдут #Н/Д splitTo3parts = Split(strSource & String(100 - WorksheetFunction.Min(colMatches.Count, 100), sep), sep, 100) End Function
как изменить количество колонок, на которые делятся предложения? Сейчас на 3 колонки делятся, в остальных написано "Н/Д"
Тю! А у меня что-то сложилось устойчивое впечатление, что надо именно по 3-м разбить: первое предложение, второе и остальной текст. "А оно вона чо, Михалыч!" (с) Ну и ладно, так ещё и проще получается.
[vba]
Код
Function splitTo3parts(ByVal strSource) Dim objRegExp As Object 'RegExp Dim colMatches As Object 'MatchCollection Dim aMatch As Object 'Match Dim sep As String
sep = vbTab
Set objRegExp = CreateObject("VBScript.RegExp") objRegExp.Global = True
'перенос строки как окончание предложения, чтобы точно так же, как предложение с точкой objRegExp.Pattern = "[^.?!]" & vbLf 'случай Alt+Enter в ячейке strSource = replaceEOL(objRegExp, strSource)
'а также неразрывного пробела - символа с кодом 160 strSource = Replace(strSource, Chr(160), " ")
'дополнительно чистим ПЕЧСИМВ (вдруг что-то еще осталось) 'и удаляем лишние пробелы With WorksheetFunction strSource = .Clean(strSource) strSource = .Trim(strSource) 'именно Trim табличной функцией End With 'здесь между символами остался максимум ОДИН пробел
'временно заменяем исключения - типа города г. и т.е., чтобы не мешались точками 'а также сюда добавим другие, если еще найдутся strSource = Replace(strSource, " г. ", " г_| ", , , vbBinaryCompare) 'заменяем только строчную "г." strSource = Replace(strSource, " т.е. ", " т_|е_| ")
objRegExp.Pattern = "[.?!]\s[A-ZА-Я0-9""]" 'добавил возможность начала предложения с цифры и двойной кавычки
Set colMatches = objRegExp.Execute(strSource)
For Each aMatch In colMatches 'меняем все совпадения (а не только первые два, как раньше) Mid(strSource, aMatch.FirstIndex + 2) = sep Next
'восстанавливаем исключения - типа города и т.е. strSource = Replace(strSource, "г_|", "г.") strSource = Replace(strSource, "т_|е_|", "т.е.")
'с защитой от #Н/Д и 0 на 100 ячеек (предложений), начиная со 101-й ячейки пойдут #Н/Д splitTo3parts = Split(strSource & String(100 - WorksheetFunction.Min(colMatches.Count, 100), sep), sep, 100) End Function
Gustav, А я сначала и не заметил, смотрю три предложения, думаю ну ладно три, а потом посчитал что их 5. Тоже пытался изменить предпоследнюю строку выражения, но не получалось. Благодарю, что изменили выражения.
Gustav, А я сначала и не заметил, смотрю три предложения, думаю ну ладно три, а потом посчитал что их 5. Тоже пытался изменить предпоследнюю строку выражения, но не получалось. Благодарю, что изменили выражения.atatat111