Re: AHK: Регулярные выражения
Чтобы искать в отдельной строке, а не во всем тексте.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Чтобы искать в отдельной строке, а не во всем тексте.
Не очень понял, в какой именно отдельной? Приведите пример, который будет демонстрировать это.
str =
(
1
2
3
)
match := "", Pos := 1
While Pos := RegExMatch(str, "m`a)^(.*)$",match,Pos+StrLen(match))
msgbox % match
А, понял. Просто в предыдущих примерах у вас однострочный текст.
Интересно, почему начальные теги не находятся в первой группе ($1), несмотря на то, что заключены в общие скобки? —
str = ( <p><p> <a><a><a><a></b><b>bold</b>bold</b><a> <blockquote></blockquote> (((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p> ) str := RegExReplace(str, "m`a)^((<[^>]*>([\s]+)?)+(?<!\w))(.*)$", "$1$2$3-----------------$4") msgbox % str
Давайте разбираться, если действительно интересно. Как определили, что не находятся?
Как определили, что не находятся?
Потому что вторая группа не начинается с «bold», а начинается с последнего тега из первой группы. Это видно, если условные «-----------------», поставить между $1 и $2 —
str =
(
<p><p> <a><a><a><a></b><b>bold</b>bold</b><a> <blockquote></blockquote> (((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p>
)
str := RegExReplace(str, "m`a)^((<[^>]*>([\s]+)?)+(?<!\w))(.*)$", "$1-----------------$2$3$4")
msgbox % str
Как в перечне в квадратных скобках указать парный символ — как один? Чтобы искалась не отдельно точка, а точка и пробел (\.\s)? Можно ли туда добавить закрывающий тег (</a>)?
Str =
(
One thing is for sure, That Poppy is actually tied to a high-level record label where <a "https://vigilantcitizen.com/musicbusiness">people do not play around</a>. Also, and more importantly, That Poppy is another proof that this is basically the one kind of messages and symbolism that is <b>allowed to be associated</b> with her, and most of pop culture. They want this Illuminati mind control symbolism to be what is cool, viral, trendy, edgy, experimental and so forth.
)
StartPos := 1
While StartPos := RegExMatch(Str, "s)(.{1,50}.+?([\.\n]+\s*|$))", Found, StartPos) + StrLen(Found)
MsgBox, % Found1
А разве начальные теги при этом не находятся в первой группе?
Находятся, но со следами в других группах, которые тоже должны использоваться.
Интересно, почему начальные теги не находятся в первой группе
То-есть, с этим вопросом разобрались?
Имелось в виду: целиком в первой группе). Я думал по этому принципу сделать потом захват конечных тегов в строке, ну и середины строки, ан нет).
Так они там разве не целиком? Понимаете, умение правильно сформулировать вопрос/задачу — это половина решения.
Вроде, если остается (пусть и дублируясь) последний тег за пределами группы — получается не целиком). Ведь и захватывать начальные теги можно было с тем, чтобы их удалять, заменять и тд. (а не извлекать) — то есть, сохраняя на месте остальное содержимое строки без изменений. Но если при этом в остатке сохраняются фрагменты предыдущей группы — это в большинстве случаев не может соответствовать ожидаеому результату. В любом случае, когда задавал вопрос не предполагал, что захват первой группы, затруднит чистое получение второй и тд.
Как в перечне в квадратных скобках указать парный символ — как один? Чтобы искалась не отдельно точка, а точка и пробел (\.\s)? Можно ли туда добавить закрывающий тег (</a>)?
Так, вроде:
Str =
(
One thing is for sure, That Poppy is actually tied to a high-level record label where <a "https://vigilantcitizen.com/musicbusiness">people do not play around</a>. Also, and more importantly, That Poppy is another proof that this is basically the one kind of messages and symbolism that is <b>allowed to be associated</b> with her, and most of pop culture. They want this Illuminati mind control symbolism to be what is cool, viral, trendy, edgy, experimental and so forth.
)
StartPos := 1
While StartPos := RegExMatch(Str, "s)(.{1,50}.+?([\.\n]+\s*|(?!</a>|\.\w)|$))", Found, StartPos) + StrLen(Found)
MsgBox, % Found1
если остается (пусть и дублируясь) последний тег за пределами группы — получается не целиком)
Нет, тут у вас явное недопонимание. Предположим, есть два объекта — две купюры по 1000 рублей. Они целиком принадлежат к одной большой группе — "изделия из бумаги". При этом они целиком же принадлежат к меньшей группе, являющейся подгруппой первой — "бумажные деньги". То, что эти два объекта принадлежат группе "изделия из бумаги", никак не мешает им целиком принадлежать группе "бумажные деньги", и наоборот.
Но ключевым здесь является то, что "захват первых тегов" не подразумевал, что остальная часть разбираемой строки не понадобится в изначальном виде. В задаче ведь не было сказано, что остальную часть строки можно не брать в расчет, и она ведь ставилась не для формального решения, а для применения на практике, где даже при вырезании/извлечении/удалении первых тегов (не говоря об их изменении) — в оставшуюся часть строки не обязательно должны попадать рабочие фрагменты шаблона из первой группы. Именно поэтому, поскольку выпадающие во вторую группу элементы первой группы не находятся в первой группе целиком (да, формально тыща рублей вся в первой группе — но после размена рублики из нее посыпались во вторую :-) — постольку и оправданно говорить, что "начальные теги не находятся в первой группе".
постольку и оправданно говорить, что "начальные теги не находятся в первой группе".
Так говорить не оправдано ничем, поскольку они таки находятся в первой группе, причём целиком. Можно сказать, что они находятся не только в первой группе, это будет оправдано. Смекаете?
Ну да, ну да. Но задача не подразумевала работу только лишь с первой группой, просекаете?
Здесь у вас логическая ошибка. Задача сама по себе ничего подразумевать не может, это лишь не очень удачная форма речи, которая не очень годится для случаев, в которых важна точность определений. Подразумевает тот, кто задачу ставит, а тот, кто её решает, выбирает средства для решения, иногда выбирает правильно, иногда нет.
Это понятно, что фигура "задача подразумевает" — имеет в виду условия ее автора, который ее ставит. Но ни сам автор не сказал о работе с первой группой в ущерб прочим, ни сама по себе задача по обработке регулярными выражениями текста, в абсолютном большинстве не означает формального решения (такова ее внутренняя имплицитная предпосылка), потому что важен бывает не только захватываемый текст, но и тот, что остается в результате. Поэтому здесь нет ни логических ошибок, ни недопонимания, ни неправильно сформулированных вопросов.
Это понятно
Это вам понятно. Остаётся сделать то, что вы «подразумеваете», понятным для интерпретатора AHK. А логическая ошибка в том, что вы почему-то думаете, что в группах, одна из которых полностью находится внутри другой не может быть общих элементов.
Ну так-то и интерпретатор не может понимать мои подразумевания — это делает тот, кто дает решение, сообразуясь с возможностями интерпретатора. И в группах могут как угодно дела обстоять, но тот, кто решает задачу исходит из юзабельности шаблона впоследствии. Скажем, есть задача захватывать начала строк — но можно ли считать решением, если потом нельзя будет без появления новых элементов — ни удалить, ни обрамить, ни вырезать, ни изменить эти начала строк?
тот, кто решает задачу исходит из юзабельности шаблона впоследствии
Это смотря, что понимать под последствиями. Если условия как-то меняются, шаблон вовсе не обязан срабатывать, а уж тем более точно так, как вы «подразумеваете».
Я говорил не об изменениях условий впоследствии, а об использовании шаблона на практике впоследствии, в котором условием подразумевается целостность строки при замене. Если в примере с шаблоном захватывается начала строки, с дублированием элементов — а на практическом примере происходит то же самое — это не изменение условий.
Я, честно говоря, уже не понимаю, что вы хотите доказать. Какой-то мой код не выполняет заявленную задачу? Так приведите этот мой код, и напомните, какая была задача.
Ну так это разбирательство не я начал ("Давайте разбираться, если действительно интересно.") и это был не ваш код). Но в вашем мне тоже не удалось разбить строку по группам:
str =
(
<p><p> <a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpgdd"><b>bold</b><a href="4rthmurla.jpg"> <blockquote></blockquote>(((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p>
)
str := RegExReplace(str, "((?<=>)\s*[^\s<].*)", "$1--------$2--------$3")
MsgBox % str
Так я говорил о том коде только в контексте вашего вопроса о принадлежности одних и тех же элементов разным группам, пытаясь вам доказать, что в этом ничего странного и неправильного нет. Мне это, я так понимаю, не удалось?
в вашем мне тоже не удалось разбить строку по группам
Повторяете ошибки, о которых уже говорилось — нет смысла брать в скобки весь шаблон целиком. И где вы нашли там группы 2 и 3? Даже с учётом вашей ошибки там всего одна. (?<=>) — это не группа, а look-behind assertion.
Неправильного может там и нет ничего, но на практике не подходит. А группы 2 и 3 я пока тестировал, добавил. Так тоже захватывается символ из второй группы:
str =
(
<p><p> <a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpgdd"><b>bold</b><a href="4rthmurla.jpg"> <blockquote></blockquote>(((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p>
)
str := RegExReplace(str, "((?<=>)\s*[^\s<])(.*)", "$1---------$2")
MsgBox % str
Не понял, куда именно захватывается? И какой символ? Здесь группы не пересекаются никак. Имейте в виду, что разделение на группы ваше, не моё.
В первую группу захватывается символ из второй группы (первая буква слова «bold»). А то что разделение на группы мое и не отрабатывает, я уже повыше намекнул.
А почему вы считаете первую букву слова «bold» символом из второй группы? Разве он есть во второй группе? Опять подразумеваете?
Конечно. В моем понимании всё, что входит в $1 — это первая группа, и тд.
Ну да, всё правильно.
Но как же правильно разделить группы?
Давайте всё же перейдём от подразумевания к формулировкам.
В смысле? Мне надо, чтобы в разделенном виде по группам находились начальные теги и остальное содержимое строки.
Всё ещё слишком много подразумевания.
Надо, чтобы в группе $1 ($2, $3...) находились начальные теги, а в следующих группах — всё, начиная от слова «bold».
Перечитайте внимательно, что написали, хорошо подумайте, попробуйте ещё раз.
Что-то я переподразумевался, действительно). Как правильно конечные теги оформить в третью группу? —
str =
(
<p><p> <a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpgdd"><b>bold</b><a href="4rthmurla.jpg"> <blockquote></blockquote>(((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p>
)
str := RegExReplace(str, "((?<=>))(\s*[^\s<].*)((?<=>)(\s*[^\s>]))", "$1---------$2---------$3")
MsgBox % str
Все никак — они идут не подряд. Вы напрасно используете RegExReplace для отслеживания содержания групп, RegExMatch для этого подходит гораздо лучше.
А как получать конечные теги в этом формате? Я бы перед ними ставил условный знак и тогда предыдущий шаблон срабатывал бы.
Смотря какова исходная строка и в каком виде их нужно получить.
Строка та же (как в 439-м посте), и получать так же, в какой-либо группе.
В одной группе не получится — они не подряд.
Все никак — они идут не подряд.
Выходит, выше Вы имели в виду, что конечные теги нельзя определить в одну группу, но можно — в нескольких? Тогда позвольте уточнить вопрос по коду из 439 поста: как правильно конечные теги оформить в последующие (после первой и второй) группы? Чтобы в нужном количестве групп последовательно находились начальные теги, потом текст посередине и конечные теги?
В несколько можно только если заранее известно их количество. Если нет — тогда только обходом в цикле.
только если заранее известно их количество
Количество конечных тегов или групп?
Тегов.
Если нет — тогда только обходом в цикле.
А как в цикле обработать тот пример?
str =
(
<p><p> <a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpg"><a href="4rthmurla.jpgdd"><b>bold</b><a href="4rthmurla.jpg"> <blockquote></blockquote>(((((((((((((((((((((( j <img src="4rthmurla.jpg"></a></blockquote></p>
)
str := MultiRegExReplace(str, "((?<=>))(\s*[^\s<].*)((?<=>)(\s*[^\s>]))", "$1---------$2---------$3")
MsgBox % str
; рекурсивная ф-ия, делающая замены, пока существуют подходящие под условия замены подстроки
MultiRegExReplace(ResponseText, regex, replacement) {
Return ResponseText = (next_str := RegExReplace(ResponseText, regex, replacement))
? ResponseText
: MultiRegExReplace(next_str, regex, replacement)
}
Вы просто напишите, что и в каких переменных в итоге должно быть.
Для кода из 439-го, хотелось бы, чтобы начальные сплошные теги (с возможными пробелами-табуляцией между ними) — были в первой переменной. Такие же конечные теги — в третьей. А то, что между ними — во второй.
Да вы буквально напишите, какой конкретно текст в какой переменной.
« <p><p> <a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpgdd'><b>bold</b><a href='4rthmurla.jpg'> <blockquote></blockquote>(((((((((((((((((((((( j <img src='4rthmurla.jpg'></a></blockquote></p> »
peremennaya1 := " <p><p> <a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpgdd'><b>"
peremennaya2 := "bold</b><a href='4rthmurla.jpg'> <blockquote></blockquote>(((((((((((((((((((((( j "
peremennaya3 := "<img src='4rthmurla.jpg'></a></blockquote></p> "
Теперь непонятно, по какому принципу составлены вторая и третья переменные. Вы писали, что в третьей конечные теги, однако я вижу в ней <img src='4rthmurla.jpg'>, что конечным тегом не является. При этом во вторую попал конечный тег.
Даю вам последнюю попытку объяснить внятно, что требуется.
Под конечными — я имел в виду, конечно же, не закрывающие теги, а те, что находятся в ломаных скобках и в самом конце строки, потому что в конце строки может встретиться вот такая конструкция тоже:
... </b><i></i></p>
Кстати, по этому же принципу работает и Ваш код, захватывающий начальные теги — независимо от того, открывающие они, или закрывающие:
((?<=>))
То есть принцип захвата следующий: в первую переменную идут начальные сплошные (с пробелами-табуляцией) теги, во вторую — всё, до конечных сплошных тегов, а в третью — конечные сплошные (с пробелами-табуляцией) теги.
Вторая переменная начинается со слова «bold», потому что «bold» не является тегом, перемежаемым табуляцией или пробелом.
Вспомнился диалог из «Бриллиантовой руки»: «Сеня, там у тебя не закрытый перелом. Там у тебя — открытый перелом!»
Под конечными — я имел в виду, конечно же, не закрывающие теги
Ах, так вот в чём дело! Надо было догадаться, что вы придаёте словам какое-то своё, заранее непредсказуемое значение! Это хоть и забавно, но, когда дело касается технических вопросов, так лучше не поступать. Синтаксис тегов.
str := " <p><p> <a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpg'><a href='4rthmurla.jpgdd'><b> bold</b><a href='4rthmurla.jpg'> <blockquote></blockquote>(((((((((((((((((((((( j <img src='4rthmurla.jpg'></a></blockquote></p> "
RegExMatch(str, "x)^(\s*) (?<one>(<[^>]+>)((?1)(?3))*) (?<two>.*?) (?<three>(?2)) (?1)$", _)
MsgBox, % "|" . _one . "|`n`n"
. "|" . _two . "|`n`n"
. "|" . _three . "|"
Спасибо! Но всё же смысл был вполне предсказуем, так как упомянутые теги бывают закрытыми и открытыми и независимо от своей закрытости-открытости — находиться в начале или конце строки (открываясь в конце одной строки, а закрываясь на следующей). То есть по смыслу начальный-конечный тег — это не обязательно открытый-закрытый.
Перешел по Вашей ссылке, а там открывающие-закрывающие теги называют начальными и конечными, имея в виду — относительно элементов, но не строки. Хотя на практике любые теги могут находиться относительно строки где угодно и не быть буквально закрывающими. К примеру, у тега <br> (<img...>, <hr> и т.д.) нет стандартной закрывающей черты, однако встречается он как правило на концах строк.
Как правильно заменить на HTML-код не парные одиночные ломаные скобки?
ttxt =
(
<p>> <[1] Filosofía en la forma pero< no en el fondo, ya que el pensamiento tradicional no parte de una duda que intenta resolver, como lo hace la filosofía actual, sino de una certeza que intenta comunicar desde distintas perspectivas.</p>
)
Loop, 20 {
ttxt := RegExReplace(ttxt, "s)^(.*)<([^>]*[<$].*)$", "$1<$2$3")
ttxt := RegExReplace(ttxt, "s)^(.*)>([^<]*[>$].*)$", "$1>$2$3")
}
MsgBox % ttxt
А как определить, какая из двух непарная?
После открывающей скобки может быть только закрывающая, и наоборот.
А какая из закрывающих правильная?
<span> id="myid"> class="myclass">bebebe></span>
Если предположить что в тэге не может быть закрывающих.
ttxt = <span> id="myid"> class="myclass">bebebe></span>>
Loop {
ttxt := RegExReplace(ttxt, "(<.*?>)[^<]*?\K(>)", "<", c, 1)
} Until !c
MsgBox % ttxt
Как всегда вопрос: в одну строчку как?
Если предположить что в тэге не может быть закрывающих.
Так очевидно же неправильно. Лишние первая, вторая и четвёртая.
serzh82saratov, если смотреть с моим примером — не парные не обрабатывает:
ttxt = <p>> <[1] Filosofía en la forma pero< no en el fondo, ya que el pensamiento tradicional no parte de una duda que intenta resolver, como lo hace la filosofía actual, sino de una certeza que intenta comunicar desde distintas perspectivas.</p>
Loop {
ttxt := RegExReplace(ttxt, "(<.*?>)[^<]*?\K(>)", "<", c, 1)
} Until !c
MsgBox % ttxt
А какая из закрывающих правильная?
<span> id="myid"> class="myclass">bebebe></span>
Первая и последняя.
То есть, между открытой и закрытой не должно быть других ломаных скобок.
Как перечисленные теги переделывать в одну строку, — то есть, чтобы например между <h2></h2> не было переводов строки?
fbody =
(
<div>
<h2>
<a class="cntr" href="https://paginatransversal.wordpress.com/2016/02/05/raices-espirituales-del-conflicto-ruso-estadounidense">Raíces espirituales del conflicto ruso-estadounidense</a>
</h2>
</div>
)
MsgBox % RegExReplace(fbody, "is)<(p|h1|h2|h3|h4|h5|h6|li)(.*?)\R(.*?)</\1>", "$1$2 </$1>")
Каким будет шаблон для поиска строк без длинного тире? А так же для строк, в которых тире два и более?
А как бы вы искали строки с одним тире?
Вот так
.*--.*
Я, честно говоря, был уверен, что длинное тире это —
Можете привести полный код с текстом?
Я пока с телефона набираю, поэтому дефис продублировал. Вечерком приведу пример.
Не, всё-таки затрудняюсь именно в коде показать. Мне нужен шаблон не для использования из кода, а в Notepade++ и подобных программах. То есть, нужен шаблон для поиска строк без тире, а так же строк, в которых тире больше одного.
В смысле задача нерешаема средствами AutoHotkey?
В смысле задача нерешаема средствами AutoHotkey?
Решаема, но там один файл всего и проще в N++ вывести всё, что предстоит заменить, просмотреть и заменить окончательно. В PowerGREP еще гибче это делается.
А каким будет шаблон для одного тире? Так не срабатывает:
(.*—.*){1}
(.*—.*){1,}
(.*—.*){,1}
(.*—.*){1,1}
^[^—]*?$ ; без тире
^[^—]*—[^—]*?$ ; одно тире
Допустимо ли использовать проверку по Regex внутри if? Как-то так, чтобы была найдена папка с именем "name", а так же "name_слово"? —
if (FileExist(A_ScriptDir "\name" (_\w+)? ))
В конструкции if допустимо использовать любое выражение или функцию, которые что-либо возвращают.