1

Тема: AHK: Поиск недостающей кавычки

И снова приветствую почтенное форумное сообщество!

Автоматизация редактуры текста идет полным ходом. Задумал написать скрипт, который вместо меня будет внимательно следить за популяцией кавычек в каждом конкретном тексте. Получился вот такой кусочек кода (наверняка кривоват, но работает):

F1::
{
clipboard =
SendInput ^a
SendInput ^c
ClipWait
RegExReplace(Clipboard, "«", "«", var1Count)
RegExReplace(Clipboard, "»", "»", var2Count)
diff1 := (var1Count-var2Count)
if diff1 < 0
{
MsgBox Пропущена «
}
if diff1 > 0
{
MsgBox Пропущена »
}
if diff1 = 0
{
MsgBox Кавычки в порядке
}
return
}

Недостаток его в том, что отсутствующую кавычку приходится искать вручную по всему тексту, то есть, к примеру, если пропущена закрывающая, приходится отсматривать все подряд открывающие. Это, конечно, долго.

Думал-думал, что можно учудить здесь, и пришла в голову вроде бы светлая мысль разбить текст, находящийся в буфере обмена, на куски (абзацы, `n) и производить поиск, обозначенный выше, именно в каждом куске по отдельности, а потом абзац, в котором количество открывающих и закрывающих кавычек не будет совпадать, вывести в сообщении. Но вот как это реализовать... Додумался до вот такого варианта:

F1::
{
clipboard =
SendInput ^a
SendInput ^c
ClipWait
for index, Paragraph in StrSplit(Clipboard, "`n")
if RegExReplace(Paragraph, "«", "«", var1Count) <> RegExReplace(Paragraph, "»", "»", var2Count) ; типа если количество открывающих кавычек не равно количеству закрывающих и наоборот
{
MsgBox, % "Элемент " Paragraph " искомый " 
}
else
{
MsgBox, Ошибка
}
}

На тестовом тексте вида

«Один абзац
«Второй абзац»
Третий абзац»
Четвертый абзац

данный код выдает "Ошибка" пять раз подряд (даром что абзацев четыре).

Пробовал подобное же организовать с помощью InStr:

F1::
{
clipboard =
SendInput ^a
SendInput ^c
ClipWait
for index, Paragraph in StrSplit(Clipboard, "`n")
if InStr(Paragraph, "«") != InStr(Paragraph, "»")
{
MsgBox, % "Элемент " Paragraph " искомый " 
}
else
{
MsgBox, Ошибка
}
}

– выдает сначала три абзаца в качестве искомых, то есть включая тот, где кавычки в полном порядке, и еще два окна с "Ошибка".

Пробовал через Loop, parse сделать, но тут тем более не понял, как обратиться к элементу массива, через A_LoopField не получается почему-то.



Помогите, пожалуйста, довести до ума скрипт, желательно как можно проще, чтобы я смог понять. Заранее спасибо, конечно!

2

Re: AHK: Поиск недостающей кавычки

Непонятно, как именно вы бы хотели, чтобы работал скрипт.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Поиск недостающей кавычки

Завершающая кавычка всегда должна быть в конце строки? Если так, можно сделать автоматическую вставку в конец при обнаружении открывающей.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit), AHK v2.0.17| AHK-Wiki | Переменные и выражения | RegEx101

4 (изменено: adeckwatt, 2024-10-16 23:50:41)

Re: AHK: Поиск недостающей кавычки

teadrinker пишет:

Непонятно, как именно вы бы хотели, чтобы работал скрипт.

Здравствуйте!

Мне бы хотелось, чтобы в каждом абзаце текста независимо от других абзацев производился подсчет количества закрывающих и открывающих кавычек. Если ни одна кавычка не пропущена (или если они вообще отсутствуют), то есть количество открывающих и количество закрывающих кавычек одинаково (в том числе 0 равен 0), то return, а если количество кавычек не совпадает, вывести в MsgBox текст абзаца, в котором количества эти разнятся. Первый приведенный мною код просто ищет во всем объеме текста, а идея в том, чтобы приспособить его высчитывать "поабзацно".

То есть общий алгоритм следующий:

1. Текст копируется в буфер обмена;
2. В буфере обмена текст делится на куски, абзацы или что-то вроде того (мне только абзацы пришли в голову, ньюлайн, которая отделяет один абзац от другого вроде как, но я могу ошибаться здесь);
3. В каждом куске независимо от других кусков производится подсчет количества кавычек открывающих и закрывающих;
4. Полученные два количества сравниваются;
5. Если количества совпадают, return (переход к следующему куску и подсчет в нем), если не совпадают – MsgBox с куском текста, в котором количества не совпадают.


__Михаил__ пишет:

Завершающая кавычка всегда должна быть в конце строки? Если так, можно сделать автоматическую вставку в конец при обнаружении открывающей.

Приветствую!

Нет, кавычки могут быть где угодно внутри абзаца. Имеем дело с обычными текстами в текстовом редакторе. Тексты разделены на абзацы через прожатие Enter (по крайней мере я так делаю); абзац состоит из предложений, и там могут быть отдельные слова в кавычках, если это названия какие-нибудь, или целые фразы, если это цитаты, так что местоположение кавычек может быть любым. Более того, обычно я забываю ставить кавычку при оформлении крупной цитаты или отрывка прямой речи, то есть открывающая кавычка может быть в нескольких строчках от закрывающей, в том числе и на другой странице и так далее. Так-то я сейчас ищу по той кавычке, которых больше: если количество открывающих больше, чем закрывающих, я ищу по открывающим до того места, где пропущена закрывающая, и наоборот.

5 (изменено: __Михаил__, 2024-10-17 00:58:17)

Re: AHK: Поиск недостающей кавычки

adeckwatt, проверьте код, если будут вопросы задавайте.

Text=
(
«Один абзац
«Второй абзац»
Третий абзац»
Четвертый абзац
)
;-------------------------------
Gui Font, s12, Arial
Gui Add, Edit, vText x8 y8 w700 h200, % Text
Gui Add, Edit, vText2 x8 y216 w700 h200 +ReadOnly
Gui Add, Button, gPaste x712 y8 w95 h30, Вставить
Gui Add, Button, gClear x712 y48 w95 h30, Очистить
Gui Add, Button, gTest x712 y104 w95 h30, Обработка
Gui Add, Button, gCopy x712 y216 w95 h30, Копировать
Gui Show, w815 h424
Return

GuiEscape:
GuiClose:
ExitApp

Paste:
GuiControl,, Text, % ClipBoard
Return

Clear:
GuiControl,, Text
Return

Copy:
Gui, Submit, NoHide
ClipBoard := Text2
Return

Test:
GuiControl,, Text2
Gui, Submit, NoHide
Done := "", Arr := StrSplit(Text, "`n", "`r"), AC := Arr.Count(), LS := StrLen(AC)
For index, txt in Arr{
 Q := CheckQuotes(txt, L, R)
 If (L != R) && (L+R > 0){	; Если пары кавычек, или их нет - пропускает строку, иначе записываем и отображаем.
  Done .= (index > 1 ? "`n" : "") Part(index, (LS < 4 ? 4:LS)) ") [" Q "]`t" txt
  If (AC < 50)			; Если строк мало - отображаем каждую:
   GuiControl,, Text2, % Done	; Вывод каждой строки по одной.
 }
}
If (AC > 49)
 GuiControl,, Text2, % Done	; Вывод всех строк за раз.
Return
;-------------------------------
CheckQuotes(Str, ByRef L = 0, ByRef R = 0){ ;01:04 17.10.2024	Вернёт кол-во кавычек в строке.
 StrReplace(Str, "«",, Count1), StrReplace(Str, "»",, Count2), L := Count1, R := Count2
 Return Count1 ", " Count2
}
;-------------------------------
Part(N, L := 4){	;00:18 02.10.2024	Дополняет число нулями слева:
 Return Format("{:0 " L "u}", N)
}
Win10x64, AHK v1.1.37.01 (Unicode 64-bit), AHK v2.0.17| AHK-Wiki | Переменные и выражения | RegEx101

6 (изменено: adeckwatt, 2024-10-17 02:26:58)

Re: AHK: Поиск недостающей кавычки

__Михаил__ пишет:

adeckwatt, проверьте код, если будут вопросы задавайте.

Это уже не код – это полноценный программный продукт! Потрясающе!!! Спасибо!!!

https://radikal.cloud/i/RvMk1B – доказательство, что все работает, ну и для наглядности (простите, не смог разобраться, как картинку вставить прямо в данное сообщение). Еще раз спасибо!

В свое оправдание скажу лишь, что, черт возьми, был на правильном пути, узнаю принципы функционирования, вижу знакомые команды, но вот их хитросплетение (иначе и не назовешь) поистине поражает. Честно, я был уверен, что просто как-то не так обращаюсь к элементу массива и достаточно буквально пары строк дополнительных к тому, до чего я уже дотумкал, чтобы получить искомый функционал...

Полагаю, кстати, что с минимальными правками данный код может быть модифицирован для поиска недостающих кавычек-завитушек и скобок всех мастей. Но эти элементы в обычных текстах сильно реже встречаются, поэтому надобности в модификации нет.

__Михаил__, написал вам в личные сообщения.