PDA

Показать полную графическую версию : [решено] Поиск и удаление строки в файле по сложным условиям


m0nkrus
24-06-2011, 11:33
Подоплека: Имеем программу Lingvo. Это мультиязычный словарь. Разработчики решили выпендриться и принудительно в разделы двуязычного направления перевода положили одноязычные словари. То есть, в разделе Ru->En лежат не только Ru-En-словари, но и Ru-Ru, и т.д. Это раздражает, поскольку хочешь получить перевод, а кроме него еще получаешь толкование слова, хотя этого не заказывал. Так вот, нужно автоматом убрать одноязычные словари из двуязычных разделов, независимо от того, какие и в каком количестве словари в этих разделах расположены.

Чтобы было понятно, я для начала приведу сильно упрощенный вариант INI-файла, с которым предстоит работать:

[Group:1049-1033]
AllDictionaries=AmericanEnglish (Ru-En);UrbanDictionary (Ru-Ru)

[Group:1049-1049]
AllDictionaries=UrbanDictionary (Ru-Ru)

Задача: Для раздела Group, у которого цифровой код различается (1049-1033 - различие, 1049-1049 - идентичный), в строке AllDictionaries нужно избавиться от подстроки с именем словаря, у которой в скобках совпадает буквенный код (Ru-Ru - совпадение, Ru-En - различие).

Постоянные элементы: Group, AllDictionaries, разделитель ";", разделители "(" и ")"; строка AllDictionaries идет сразу за строкой Group
Переменные элементы: 1049-1033 - цифры в строке могут быть любыми, так как групп много; UrbanDictionary - может быть любым, (Ru-Ru) - буквенная часть может быть любой.


Механизм должен быть примерно следующим:
- Ищем строку, начинающуюся с "[Group:"
- Проверяем, чтобы подстрока от ":" до "-" не совпадала с подстрокой от "-" до "]"
- Если совпадает, то ищем следующую строку, начинающуюся с "[Group:". А если не совпадает, то начинаем анализ строки, начинающейся с "AllDictionaries=", расположенной сразу под строкой "[Group:"
- В строке "AllDictionaries=" ищем подстроку, ограниченную скобками "(" и ")" и в ней проверяем, чтобы подстрока от "(" до "-" не совпадала с подстрокой от "-" до ")"
- Если нет совпадения, то переходим к поиску следующей подстроки, ограниченной скобками "(" и ")", в строке "AllDictionaries=". А если совпадение есть, то удаляем подстроку, включающую проверенные элементы и ограниченную либо "=" и ";", либо ";" и ";", либо ";" и символом конца строки. Здесь нужно быть аккуратным, чтобы случайно не удалить несколько подстрок с именами словарей от "=" до ";" или от ";" до символа конца строки.
- Продолжаем поиск, проверку и удаление (если нужно) подстрок в строке "AllDictionaries=" с использованием шаблона выше.
- Как только оказались проверенными и переработанными все подстроки в строке "AllDictionaries=", начинаем искать следующую строку, начинающуюся с "[Group:", где все повторяем заново. И так до конца файла.

amel27
24-06-2011, 17:54
В строке "AllDictionaries=" ищем подстроку, ограниченную скобками "(" и ")" и в ней проверяем, чтобы подстрока от "(" до "-" не совпадала с подстрокой от "-" до ")" »1. могут ли разделители "(",")" и "-" встречаться в именах словарей, т.е. помимо структур "(XX-YY)" ?
2. кодировка исходного/конечного файла: ANSI/OEM/UTF8 (BOM)/UTF16 ?

P.S. в упор не нахожу в LINGVO ничего похожего на такой INI, где он хоть применяется-то?

m0nkrus
24-06-2011, 21:41
amel27, файл лежит по пути: %USERPROFILE%\Local Settings\Application Data\ABBYY\Lingvo\15.0\Dic\dictconf.ini
А еще здесь: %ALLUSERSPROFILE%\ABBYY\Lingvo\15.0\Dic\dictconf.ini

Наверное, проще, если ты сам посмотришь, раз у тебя есть Lingvo, нежели я тебе буду все расписывать.

amel27
25-06-2011, 11:30
Наверное, проще, если ты сам посмотришь, раз у тебя есть Lingvo, нежели я тебе буду все расписывать. »в моём 11-м нет такого, иногда проще выложить сам файл чем "расписывать",
пришлось качать весь дистрибутив и выдергивать оттуда один файл 182Кб (!),
по содержимому вроде похож, хотя называется по другому, кодировка юникодовая (UTF16LE)@(SetLocal EnableDelayedExpansion
set "$g=0"& for /f "tokens=1* delims=:" %%a in ('type "%~1"^|findstr/n $') do @(set "$a=%%b"& set "$="
if /i "!$a:~,7!"=="[Group:" set/a "$g=!$a:~7,-1!"
if /i "!$a:~,16!"=="AllDictionaries=" if !$g! neq 0 (set ^"$a=!$a:;=^

!"
for /f "tokens=1-3 delims=(-)" %%x in ("!$a:~16!") do @if /i not "%%y"=="%%z" set "$=!$!%%x(%%y-%%z);")
if defined $ (echo AllDictionaries=!$:~,-1!) else echo:!$a!))>"%~n0.tmp"
@(set/p .="яю"& cmd/u /c type "%~n0.tmp")>"%~1"<nul
пример запуска:DicFix.BAT dictinst.ini
P.S. Код скрипта копипастить в WIN (ANSI) кодировке!

m0nkrus
25-06-2011, 11:52
amel27,
в моём 11-м нет такого, иногда проще выложить сам файл чем "расписывать"
Извини, не думал, что ты юзаешь такую древнюю версию. В противном случае бы выложил файл.
пришлось качать весь дистрибутив и выдергивать оттуда один файл 182Кб (!),
по содержимому вроде похож, хотя называется по другому, кодировка юникодовая (UTF16LE)
Это действительно не тот файл. Нужный формируется при установке. Но структура у них в нужном куске кода идентичная, так что он пойдет.

Один момент: получившийся файл получается уже не в юникоде. Можно это как-то исправить? Там в конце файла в блоках Localization тексты на разных языках, от польского до китайского.

Второй момент: можно еще жестко задать в скрипте путь к файлу как %USERPROFILE%\Local Settings\Application Data\ABBYY\Lingvo\15.0\Dic\dictconf.ini ?

Третий момент: остается временный файл DicFix.tmp.

Iska
25-06-2011, 13:29
Один момент: получившийся файл получается уже не в юникоде.
А в чём ещё? Правильно amel27 говорит, выложите сюда Ваши файлы. Лучше в архиве, дабы избежать искажений.

amel27
25-06-2011, 21:34
получившийся файл получается уже не в юникоде. Можно это как-то исправить? »исправил, ввиду наличия в коде спецсимволов оформил аттачем

P.S. Всё-таки CMD не предназначен для обработки сложных многоязыковых файлов, так как он работает с однобайтовыми OEM/ANSI строками. Т.е. чтобы пройти циклическое преобразование, обрабатываемый набор символов должен укладываться в ANSI/OEM текущей локали. Чтобы обойти это ограничение, в качестве рабочей кодировки я использовал UTF8, но это "трикс" а не правило - в некоторых случаях (на этапе UTF8 -> UTF16) может происходить искажение отдельных символов.

m0nkrus
25-06-2011, 23:23
amel27, одна строка незапланировано "поплыла":
[ProfilesGuids]
AllDictionaries={37B46E9E-5A85-4C55-8B24-56C9D8EE612F}
превратилось в:
[ProfilesGuids]
AllDictionaries={37B46E9E(5A85-4C55)

И, все-таки, можно жестко задать путь, как я просил? Он всегда один и тот же на любых виндах.

Iska, специально для Вас аттач.

amel27
26-06-2011, 08:40
m0nkrus, перевыложил в посте #7

m0nkrus
26-06-2011, 10:37
amel27, спасибо. То, то надо!




© OSzone.net 2001-2012