Добрый день. Есть текст который содержит русские и английские слова, нужен макрос который будет производить замену в выделенном диапазоне символа в слове по условию
Пока писал этот пример подумал, может лучше реализовать так, брать слово например "мамонт" "MAMONT" проверять каких символов больше те символы и являются главными, а затем производить замену символа который не родной в написании --- (КРАСНЫМ ВЫДЕЛИЛ РУС.СИМВОЛЫ) MAMONT - заменит на латинские MA веди латинских символов больше MAMONT - латинских больше, M и T заменятся на латинские MAMONT - русских больше но замены нет, ведь у N нет похожего символа в русском MAMONT - русских больше T заменится на русскую MAMONT - Латинских и русских поровну замены нет (определить невозможно)
сковородка BESITA- в первом слове больше русских сим, латинские заменятся на русские "о" "a", во втором слове больше латинских русская Е заменится на латинскую E шолох- в этом случае латинских больше но замены нет, потому что нету аналогичных символов замены секрет axyko-в первом слове нет замены количество знаков одинаковое, во втором слове k заменится на русскую к, русских знаков больше
---- E223MRTFF-Заменит М на латинскую, латинских больше O123AAA-Заменит О на русскую, русских больше A33TTF90WT-Замены нет знаков поровну --- Замена всех соответствующих знаков Rus = "асекорхуАСЕНКМОРТХ" Eng = "acekopxyACEHKMOPTX" --- Пример (красным пометил не родные буквы) --- руccкий патрoн Tinкoff крeдиты зaйы унылый МАМONT E72RUS/RFТ Аsus E223MRTFF
В вашей задаче есть пара если: если слово начинается/заканчивается с/на латиницы, дальше идет кириллица. если латиница и кириллица идут через символ, например аdарtеr здесь только последняя кириллическая е соответствует вашему ТЗ, но по сути переделывать надо все слово в латиницу. Может все таки нужно найти в слове символы, которые точно не имеют аналогов в другой раскладке, по ним определить язык раскладки, а потом уже все символы этого слова переделывать под обнаруженный язык?
Возможно ваш вариант лучше. Меня в конченом итоге интересует как это реализовать. --- Тогда можно рассмотреть еще варианты проблем ---красным помечены рус.сим ЕA GАМЕ-Нет изменений ведь у G нет аналогов в русском языке EА GАМE-Нет изменений ЕА GАMЕ --- Пока писал этот пример подумал, может лучше реализовать так, брать слово например "мамонт" "MAMONT" проверять каких символов больше те символы и являются главными, а затем производить замену символа который не родной в написании MAMONT - заменит на латинские MA веди латинских символов больше MAMONT - латинских больше, M и T заменятся на латинские MAMONT - русских больше но замены нет, ведь у N нет похожего символа в русском MAMONT - русских больше T заменится на русскую MAMONT - Латинских и русских поровну замены нет (определить невозможно) ---- E223MRTFF-Заменит М на латинскую, латинских больше O123AAA-Заменит О на русскую, русских больше A33TTF90WT-Замены нет знаков поровну --- Замена всех соответствующих знаков Rus = "асекорхуАСЕНКМОРТХ" Eng = "acekopxyACEHKMOPTX"
Если английскую "е" окружает 2 русских символа то заменить ее на русскую "е"
Код
Function ZamenaNaRus(cell As String, repl As String)
Dim objRegExp As Object
Set objRegExp = CreateObject("VBScript.RegExp")
objRegExp.Global = True
objRegExp.IgnoreCase = False
objRegExp.Pattern = "([а-я])(e)([а-я])"
ZamenaNaRus = objRegExp.Replace(cell, "$1" & repl & "$3")
End Function
Спасибо, но это транслит с русского на английский. Не то что нужно. Текст может состоять из английских и русских слов, ошибки могут быть как там и там. Нужно что бы замена была по условию как я описал выше. --- черный всадник EVIL GOD -- Если русских символов больше то заменить не родной знак на аналогичный русский Если больше латинских то заменить не родной знак на латинский
Сделал по своему алгоритму, описанному в посте №2 вариант на PQ: Не шибко быстрый: 10к строк обработал за 20 секунд. В зеленую табличку в столбец Слова вставляете строки, которые нужно преобразовать, потом жмете ПКМ по таблице, выбираете "обновить" и ждете результат.
Скрытый текст
Код
let
UniversalLetters = Table.Buffer( Excel.CurrentWorkbook(){[Name="Справочник"]}[Content] ),
TabEng = Table.AddColumn( Table.FromColumns( {{"A".."Z","a".."z"}}, {"letter"} ), "lang", each "eng" ),
TabRus = Table.AddColumn( Table.FromColumns( {{"А".."Я","а".."я","ё","Ё"}}, {"letter"} ), "lang", each "rus" ),
TabEngRusU = Table.Buffer( (Table.Join( TabRus, {"letter"}, UniversalLetters, {"rus"}, JoinKind.LeftAnti) & Table.Join( TabEng, {"letter"}, UniversalLetters, {"eng"}, JoinKind.LeftAnti) )[[letter],[lang]] ),
TabEngRus = Table.Buffer( Table.AddColumn( TabRus & TabEng, "w", each "w" ) ),
Source = Excel.CurrentWorkbook(){[Name="Слова"]}[Content][[Слова]],
AddedCustom = Table.AddColumn(Source, "Таб", each
let
ToTable = Table.FromColumns( {Text.ToList([Слова])} ),
AddedIndex = Table.AddIndexColumn(ToTable, "Индекс", 0, 1),
MergedW = Table.Join( AddedIndex, {"Column1"}, TabEngRus, {"letter"}, JoinKind.LeftOuter )[[Column1],[Индекс],[w]],
MergedU = Table.Join( MergedW, {"Column1"}, TabEngRusU, {"letter"}, JoinKind.LeftOuter ),
SortedRows = Table.Sort(MergedU,{{"Индекс", Order.Ascending}}),
GroupedWords = Table.Group(SortedRows, {"w"}, {{"таб", each [t=Table.Buffer(_), a = List.RemoveNulls( List.Distinct(t[lang]) & {"rus"} ){0}?, b = Table.RemoveColumns( Table.Join( t, {"Column1"}, UniversalLetters, {List.RemoveItems({"rus","eng"}, {a}){0}}, JoinKind.LeftOuter), {a})][b], type table}}, GroupKind.Local),
Combine = Table.Combine( GroupedWords[таб] ),
SortedRows2 = Table.Sort(Combine,{{"Индекс", Order.Ascending}}),
Result = Table.AddColumn(SortedRows2, "Итог", each let text = Text.Combine({[letter],[rus],[eng]}) in if text = "" then [Column1] else text ),
RemovedColumns = Text.Combine( Result[Итог] ) /*Table.RemoveColumns(Result,{"Индекс", "w", "letter", "lang", "rus", "eng"})*/
in
RemovedColumns
)
in
AddedCustom
Sub Мяу()
Const replaceEnRus$ = "acekopxyACEHKMOPTXасекорхуАСЕНКМОРТХ" '18/36
Dim cel As Range, t
Dim i&, j&
Dim s$, ss$
With CreateObject("VBScript.RegExp")
.Global = True
.IgnoreCase = True
For Each cel In Selection
t = Split(cel.Value)
For i = 0 To UBound(t)
.Pattern = "[^а-яё]"
If .test(t(i)) Then
s = .Replace(t(i), "")
.Pattern = "[^a-z]"
If .test(t(i)) Then
ss = .Replace(t(i), "")
If Len(ss) < Len(s) Then
For j = 1 To 18
t(i) = Replace(t(i), Mid$(replaceEnRus, j, 1), Mid$(replaceEnRus, j + 18, 1))
Next
ElseIf Len(ss) > Len(s) Then
For j = 19 To 36
t(i) = Replace(t(i), Mid$(replaceEnRus, j, 1), Mid$(replaceEnRus, j - 18, 1))
Next
End If
End If
End If
Next
cel.Value = Join(t)
Next
End With
End Sub
макрос работает немного некорректно со знаками - / . , --- Антрацит XH-09 - ХН заменяет на русские символы IP-камера - P заменяется на русскую Красный/Red - e в слове Red меняется на русскую Apple,pyc - рус меняется на латинские Apple.pyc - рус меняется на латинские
Признаки слова Суммируя предыдущие рассуждения, укажем некоторые признаки слова: определенная фонетическая оформленность, ударение; материальность (звучание и буквенное отображение); Подробнее: https://russkiiyazyk.ru/leksika/chto-takoe-slovo.html С случае, когда слово не является словом, а представляет собой набор символов, под "словом" понимается фрагмент текста, разделенный пробелами. И правила определения языка применяются ко всему фрагменту, а не его части.
Ок. Тогда можно перед выполнением макроса присвоить этим знакам пробел "-" " -" "." " ." А после выполнения этот пробел убрать. RAN, Спасибо за макрос, очень годный
Когда-то давным-давно, во времена благословенного Excel 2003, решал такую же задачу. Макроса уже нет, идею примерно помню. Решал "от обратного": 1. Есть список "исконно русских" букв: БГДЁЖЗИЙЛПУФЦЧШЩЬЫЪЭЮЯбвгдёжзиёклмнптфцчшщьыъэюя 2. Если хоть одна буква встречается в проверяемом слове, то слово считается русским и все прочие латинские буквы меняются на русские аналоги. Список тоже есть, соответствует указанному в предыдущих ответах. 3. Есть список "исконно латинских" букв: DFGIJLNRSUVYZbdfghijklmnrstuvz. 4. Если русских букв нет, но есть хотя бы одна латинская буква из списка, то слово считается "латинским", с заменой также по списку.
Возникали какие-то мелкие нюансы, типа считать ли одним словом набор букв с дефисом и т.п., с ходу их не помню, но они тоже были вполне решаемы. Понятно, что слова типа РЬl)|(ий кom, где одновременно есть и те, и те, и левые символы, считаются ошибкой и по ним исправляется вручную. То же касалось названий с цифрами.
tolikt, идея от обратного тоже годно, но список слов который можно написать без исконно русских и латинских букв огромен. МАВР МАВРО МОСКВА РОМАН ВЕРСТАК МАСТЕРОК
DartoArem, Для разрешения подобных спорных ситуация потребуется обращаться к словарям... или просто назначить язык по умолчанию и переводить на него все спорные символы, кроме тех, что находятся в словах, содержащих уникальные буквы другого языка...
Тут, как в старом еврейском анекдоте, и DartoArem прав, и IKor прав. Я же предлагаю пока пойти по простому пути. А именно, сначала отсеять слова с заведомо "исконными" рус и лат буквами, а оставшиеся проверять не словарями, а вручную. Ибо всякие слова типа МОСКВА - это из разряда ошибок, как я писал выше. Конечно, в моём случае было проще: там был именно в основном текст с вкраплениями лат. букв, а не мудрёный прайс-лист, или что-то подобное. Т.е. я решал свою задачу и просто предлагаю использовать этот подход для частичного решения текущей. Можно рассмотреть такой пример текста: Политика конфиденциальности. Во вложении этот текст на листе Excel и макрос подкраски слов с только "общечеловеческими" буквами, т.е. где нет ни одной "исконной" буквы. Как видно, подкрашены только цифровые слова (числа), предлоги и слово "Все". Т.е. в данном случае проблема решена на 99.9%. Если макрос доработать на пропуск чисел и однобуквенных предлогов, то проблема решена на 99.99%. Слово "Все" можно проверить без подключения доп.словарей. Для хитромудрого прайс-листа, конечно, доля ручной работы увеличится. И конечно же, надо дописать доп.проверку сложносоставных слов через дефис, точку и т.п.: IP-камера, www.планетаэксель.рф, Красный/Red и др. Но, как я предлагал выше, чаще всего их проще проверить вручную, ибо время написания процедуры для проверки таких слов бывает обычно больше, чем время ручной проверки.