Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Скрытие ответов в тестах

#регулярные_выражения #sublime_text #sublime_text_3 #pcre


Здравствуйте, имеются готовые текстовые документы с тестовыми заданиями. Их содержимое:

Тема 1: Стихийные бедствия.
Автор: Булат Фаттахов
10. Таким женским именем звали ураган, сильно повредивший Новый Орлеан.
Ответ: Катрина.
20. "Дождь лил четыре года, одиннадцать месяцев и два дня" именно там.
Ответ: в Макондо.
30. В 1883 году было извержение вулкана именно на этом острове.
Ответ: Кракатау (Остров назывался так же как и вулкан).
40. Армянские города Гюмри и Ванадзор, сильно пострадавшие во время землетрясения
1988 года, в советское время носили такие названия.
Ответ: Ленинакан и Кировокан.
50. Крупнейшее за всю историю человечества это стихийное бедствие произошло в 1875
году в США, а не в Египте двумя тысячами годами ранее.
Ответ: Нашествие саранчи.

Тема 2: Города России.
Автор: Булат Фаттахов
10. Это крупнейший город России после Москвы.
Ответ: Санкт-Петербург.
20. Москва крупнейший город России, а Тольятти тоже крупнейший город в России среди
таких.
Ответ: Не являющийся столицей региона.
30. Это - крупнейший город самого большого острова России.
Ответ: Южно-Сахалинск.
40. Именно в этом городе происходит действие сериала "Счастливы вместе".
Ответ: Екатеринбург.
50. А именно этот город является самым западным городом России.
Ответ: Балтийск.


И так на протяжении всех файлов. я не хочу сразу видеть то, что содержится после
«Ответ». Нужно, чтобы ответы изначально были скрыты, становясь видимыми только тогда,
когда пользователь выполняет какое-то действие, например, нажимает на «Развернуть ответ».

Методы не имеют значения. Да, можно заключить ответы под спойлеры — в HTML, например,
проще всего в тэг  — Ответ:
Текст ответа
(что он не поддерживается IE и Firefox, ничего страшного) . Но как выполнить множественные замены (учитывая, что ответы могут быть в несколько строк), например, при помощи программы Sublime Text, поддерживающей регулярные выражения PCRE? Ответ: 'Текст ответа' 20. → Ответ:
'Текст ответа'
20. Ответ: 'Текст ответа' Тема → Ответ:
'Текст ответа'
Тема Спасибо.


Ответы

Ответ 1



Если в конце ответа обязательно цифра следующего вопроса или пустая строка, за которые можно зацепиться, то в Sublime можно так: Find What: ^Ответ: ((.|\n)+?)\n([0-9\n]) Replace With: Ответ:
\1
\n\3 (где \1 и \3 означают содержимое первой и третьей пар скобок в регулярке) (Немного пояснений: (.|\n)+ — берём один или больше любых символов, даже перенос строки, а +? — включаем ленивый режим работы вместо жадного, чтобы регулярка не считала одним ответом всё с начала первого ответа до конца последнего)

Ответ 2



В Notepad++ замена регулярные выражения с отмеченным флажком И новые строки. Исходный текст Тема 1: Стихийные бедствия. Автор: Булат Фаттахов 10. Таким женским именем звали ураган, сильно повредивший Новый Орлеан. Ответ: Катрина. 20. "Дождь лил четыре года, одиннадцать месяцев и два дня" именно там. Ответ: в Макондо. 30. В 1883 году было извержение вулкана именно на этом острове. Ответ: Кракатау (Остров назывался так же как и вулкан). 40. Армянские города Гюмри и Ванадзор, сильно пострадавшие во время землетрясения 1988 года, в советское время носили такие названия. Ответ: Ленинакан и Кировокан. 50. Крупнейшее за всю историю человечества это стихийное бедствие произошло в 1875 году в США, а не в Египте двумя тысячами годами ранее. Ответ: Нашествие саранчи. Тема 2: Города России. Автор: Булат Фаттахов 10. Это крупнейший город России после Москвы. Ответ: Санкт-Петербург. 20. Москва крупнейший город России, а Тольятти тоже крупнейший город в России среди таких. Ответ: Не являющийся столицей региона. 30. Это - крупнейший город самого большого острова России. Ответ: Южно-Сахалинск. 40. Именно в этом городе происходит действие сериала "Счастливы вместе". Ответ: Екатеринбург. 50. А именно этот город является самым западным городом России. Ответ: Балтийск. Замена 1: ((\d+)\. ((?!\r\nОтвет:).)+) Результат: Тема 1: Стихийные бедствия. Автор: Булат Фаттахов Ответ: Катрина. Ответ: в Макондо. Ответ: Кракатау (Остров назывался так же как и вулкан). Ответ: Ленинакан и Кировокан. Ответ: Нашествие саранчи. Тема 2: Города России. Автор: Булат Фаттахов Ответ: Санкт-Петербург. Ответ: Не являющийся столицей региона. Ответ: Южно-Сахалинск. Ответ: Екатеринбург. Ответ: Балтийск. Замена 2: (\r\n)(Ответ: ((?!\r\n(Тема:|\2
Результат: Тема 1: Стихийные бедствия. Автор: Булат Фаттахов
Ответ: Катрина.
Ответ: в Макондо.
Ответ: Кракатау (Остров назывался так же как и вулкан).
Ответ: Ленинакан и Кировокан.
Ответ: Нашествие саранчи. Тема 2: Города России. Автор: Булат Фаттахов
Ответ: Санкт-Петербург.
Ответ: Не являющийся столицей региона.
Ответ: Южно-Сахалинск.
Ответ: Екатеринбург.
Ответ: Балтийск.
Замена 3: (Тема (\d+).*?)(\r\n\1\3 Результат:

Тема 1: Стихийные бедствия. Автор: Булат Фаттахов

Ответ: Катрина.
Ответ: в Макондо.
Ответ: Кракатау (Остров назывался так же как и вулкан).
Ответ: Ленинакан и Кировокан.
Ответ: Нашествие саранчи.

Тема 2: Города России. Автор: Булат Фаттахов

Ответ: Санкт-Петербург.
Ответ: Не являющийся столицей региона.
Ответ: Южно-Сахалинск.
Ответ: Екатеринбург.
Ответ: Балтийск.
Замена 4: (id=sec-(\d+).*?)(id|for)(=chk)(\d+) \1\3\4-\2-\5 Нажимать Заменить все до тех пор, пока количество замен не станет равным нулю. Это будет в 2 раза больше нажатий, чем вопросов в самой большой теме. В принципе, можно уменьшить число нажатий вдвое. Результат:

Тема 1: Стихийные бедствия. Автор: Булат Фаттахов

Ответ: Катрина.
Ответ: в Макондо.
Ответ: Кракатау (Остров назывался так же как и вулкан).
Ответ: Ленинакан и Кировокан.
Ответ: Нашествие саранчи.

Тема 2: Города России. Автор: Булат Фаттахов

Ответ: Санкт-Петербург.
Ответ: Не являющийся столицей региона.
Ответ: Южно-Сахалинск.
Ответ: Екатеринбург.
Ответ: Балтийск.
Замена 5 (исправляем косяк, сделанный раньше) (\s*)() \2\1\3 Добавляем немного css: input { display: none; } input + label + div { display: none; } input:checked + label + div { display: block; } label { display: block; cursor: pointer; margin-top: 1em; } label:hover { color: blue; } label, div, h1 { white-space: pre-wrap; }

Тема 1: Стихийные бедствия. Автор: Булат Фаттахов

Ответ: Катрина.
Ответ: в Макондо.
Ответ: Кракатау (Остров назывался так же как и вулкан).
Ответ: Ленинакан и Кировокан.
Ответ: Нашествие саранчи.

Тема 2: Города России. Автор: Булат Фаттахов

Ответ: Санкт-Петербург.
Ответ: Не являющийся столицей региона.
Ответ: Южно-Сахалинск.
Ответ: Екатеринбург.
Ответ: Балтийск.


Ответ 3



Т. к. вопрос практический, позволю себе дополнить ответ ув-мого andreymal. Сначала желательно заменить слово или фразу, при нажатии на которое выводится спойлер, — например, в Chrome это «Подробнее», — при помощи тега . Если хотим кликать сразу на «Ответ», замена выйдет следующей: Find What: ^Ответ: ((.|\n)+?)\n([0-9\n]) Replace With:
Ответ:\1
\n\3 Затем, чтобы тэги отображись в Firefox, Edge и Opera Mini, требуется подключить скрипт Details-Polyfill. Для Эксплорера, к сожалению, и этот метод не работает, проверял на IE NetRenderer. Принцип действия скрипта: если браузер поддерживает
и , то ничего не происходит; не поддерживает — задействуется. Когда спойлеров множество, то, увы, достаточно продолжительное время, почему от просмотра в Firefox лучше всё же воздержаться. Итог см. в коде. /* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ (function (doc) { 'use strict'; var i, j, textWrapper, idCount = 0, rootNode = doc.documentElement, headElem = doc.getElementsByTagName('head')[0] || rootNode, bodyElem = doc.getElementsByTagName('body')[0] || rootNode, detailStyleTag = doc.createElement('style'), rules = 'details { display: block; overflow:hidden; } \n' + 'details[open] { height: auto; } \n' + 'summary { display:inline-block; } \n' + 'details * { visibility: hidden; } \n' + 'summary:first-child { visibility: visible; cursor: pointer; } \n' + 'details[open] * { visibility: visible } \n' + 'details[open] summary { margin-bottom: 0; }', /* Technically, a summary element has a "Phrasing content" model and should be displayed inline. * see http://dev.w3.org/html5/spec/Overview.html#the-summary-element, * http://dev.w3.org/html5/spec/Overview.html#phrasing-content * * FYI: Chrome currently and incorrectly treats the element as block level. */ addRule = function (styleTag, rule) { if (styleTag.nodeName.toLowerCase() === 'style') { if (!!styleTag['styleSheet'] && styleTag.styleSheet['cssText'] !== undefined) { //for MSIE styleTag.styleSheet.cssText += '\n' + rule; } else { styleTag.appendChild(doc.createTextNode('\n' + rule)); } } }, addEvent = function (el, eventName, f) { //W3C event biding if (el.addEventListener) { el.addEventListener(eventName, f); //IE event binding } else if (el.attachEvent) { el.attachEvent('on' + eventName, f); // Fallback, but don't overwrite a preexisting "onclick" attribute. } else if (el['on' + eventName] === null) { el['on' + eventName] = f; } }, toggle = function (e) { /* When a element is clicked the parent
element's "open" * attribute needs to be toggled to maintain the attribute's reflective nature. * see http://dev.w3.org/html5/spec/Overview.html#attr-details-open */ var detailsElmnt, target = e.target || e.srcElement; if (target.nodeName.toLowerCase() === 'summary') { detailsElmnt = target; while (detailsElmnt.nodeName.toLowerCase() !== 'details') { detailsElmnt = detailsElmnt.parentNode; //Break if we get to the root node without finding a details element. if (detailsElmnt === bodyElem) { detailsElmnt = null; break; } } if (detailsElmnt) { if (detailsElmnt.getAttribute('open')) { detailsElmnt.removeAttribute('open'); } else { detailsElmnt.setAttribute('open', 'open'); } bodyElem.className = bodyElem.className; } } }, init = function () { var detailsID, detailsElem, summaryElem, height, //height of the summary element detailsElems = doc.getElementsByTagName('details'); for (i = 0; i < detailsElems.length; i++) { detailsElem = detailsElems[i]; if (!detailsElem.getAttribute('data-detailsid')) { detailsID = 'd' + (idCount++); detailsElem.className += (' ' + detailsID); detailsElem.setAttribute('data-detailsID', detailsID); /* The spec expects the functional element to be the first child node of a *
element. In practice, it appears the first child element of a * element is enlisted as the functional element and displayed as * though it were the first child. For our purposes, we will do that explicitly. * Additionaly, If a element does not exist, a default toggle is provided. */ summaryElem = detailsElem.getElementsByTagName('summary')[0]; if (!summaryElem) { summaryElem = doc.createElement('summary'); summaryElem.appendChild(doc.createTextNode('Details')); detailsElem.insertBefore(summaryElem, detailsElem.firstChild); } else if ( summaryElem !== detailsElem.firstChild) { detailsElem.removeChild(summaryElem); detailsElem.insertBefore(summaryElem, detailsElem.firstChild); } height = summaryElem.offsetHeight; addRule(detailStyleTag, 'details.' + detailsID + ' { height: ' + height + 'px; }\n' + 'details.' + detailsID + '[open] { height: auto; }'); //Text nodes are killing me here. Thanks to @Remy for the solve. // Weighing the pros and cons of using a standard element like or vs a non-standard // but more semantically meaninfull element, I think wins, though not without some // regret. for (j = 0; j < detailsElem.childNodes.length; j++ ) { if (detailsElem.childNodes[j].nodeName === '#text' && (detailsElem.childNodes[j].nodeValue||'').replace(/\s/g, '').length) { textWrapper = document.createElement('text'); textWrapper.appendChild(detailsElem.childNodes[j]); detailsElem.insertBefore(textWrapper, detailsElem.childNodes[j]); } } } } }; /* * The inserted stylesheet needs to be first so as to have a minimal cascading coeffecient. * It also needs to be added to the DOM before IE can access it's properties. * The polyfill only adds default or necessary styling and should not interfere with other style rules. */ headElem.insertBefore(detailStyleTag, headElem.firstChild); init(); addRule(detailStyleTag, rules); addEvent(bodyElem, 'click', toggle); addEvent(bodyElem, 'DOMSubtreeModified', init); }(document, undefined)); details Тема 1: Стихийные бедствия. Автор: Булат Фаттахов 10. Таким женским именем звали ураган, сильно повредивший Новый Орлеан.
Ответ:Катрина.
20. "Дождь лил четыре года, одиннадцать месяцев и два дня" именно там.
Ответ:в Макондо.
30. В 1883 году было извержение вулкана именно на этом острове.
Ответ:Кракатау (Остров назывался так же как и вулкан).
40. Армянские города Гюмри и Ванадзор, сильно пострадавшие во время землетрясения 1988 года, в советское время носили такие названия.
Ответ:Ленинакан и Кировокан.
50. Крупнейшее за всю историю человечества это стихийное бедствие произошло в 1875 году в США, а не в Египте двумя тысячами годами ранее.
Ответ:Нашествие саранчи.
Тема 2: Города России. Автор: Булат Фаттахов 10. Это крупнейший город России после Москвы.
Ответ:Санкт-Петербург.
20. Москва крупнейший город России, а Тольятти тоже крупнейший город в России среди таких.
Ответ:Не являющийся столицей региона.
30. Это - крупнейший город самого большого острова России.
Ответ:Южно-Сахалинск.
40. Именно в этом городе происходит действие сериала "Счастливы вместе".
Ответ:Екатеринбург.
50. А именно этот город является самым западным городом России.
Ответ:Балтийск.
UPD: начиная с 47-й версии Firefox поддерживает теги и
. Чтобы увидеть в Firefox действие тегов, пользователю необходимо ввести в адресную строку этого браузера about:config → Я обещаю, что буду осторожен → в строке поиска найти параметр dom.details_element.enabled → установить ему значение true.

Комментариев нет:

Отправить комментарий