Мне нужна функция, которая ведет себя аналогично поведению sscanf
Например, давайте предположим, что у нас есть строка формата, которая выглядит так (функция, которую я ищу, не обязательно должна быть именно такой, но что-то похожее)
"This is normal text that has to exactly match, but here is a ${var}"
И вернуть/изменить переменную, чтобы она выглядела как
{'var': <whatever was there>}
После некоторого исследования я смог найти только scanf
, но это принимает форму ввода stdin
, а не строку.
Я знаю, что для этого есть решение с регулярным выражением, но я ищу функцию, которая делает это без необходимости в регулярном выражении (регулярное выражение медленное). Однако, если для этого нет другого решения, я приму решение с регулярным выражением.
@Danizavtz Кажется, он принимает только ввод из командной строки
Вы хотите, чтобы ${var}
выступал в качестве заполнителя? Если это так, вы можете сделать это, заменив "
обратной галочкой:
console.info(`This is normal text that has to exactly match, but here is a ${"whatever was there"}`)
Я не уверен, что вы понимаете, что на самом деле делает sscanf
. Он принимает строку и еще одну строку и анализирует ее в соответствии со строкой формата. Я хочу что-то похожее на это, но вместо создания этой строки наоборот
О, хорошо, извините, я неправильно истолковал ваш вопрос.
Обычным решением для этого в большинстве языков со встроенными регулярными выражениями является использование регулярных выражений.
Если вы не привыкли или не любите регулярные выражения, извините. Большая часть мира программирования предположила, что знание регулярных выражений является обязательным.
В любом случае. Нормальное решение для этого string.prototype.match
:
let text = get_string_to_scan();
let match = text.match(/This is normal text that has to exactly match, but here is a (.+)/);
if (match) { // match is null if no match is found
// The result you want is in match[1]
console.info('value of var is:', match[1]);
}
Какой шаблон вы поместите в свою группу захвата (часть (..)
), зависит от того, что вы хотите. Приведенный выше код фиксирует все, включая пробелы и специальные символы.
Если вы просто хотите захватить «слово», то есть печатные символы без пробелов, вы можете использовать (\w+)
:
text.match(/This is normal text that has to exactly match, but here is a (\w+)/)
Если вы хотите записать слово только с буквами, но без цифр, вы можете использовать ([a-zA-Z]+)
:
text.match(/This is normal text that has to exactly match, but here is a ([a-zA-Z]+)/)
Именно из-за гибкости регулярных выражений другие методы сканирования строк обычно не поддерживаются в языках, в которых с самого начала были встроены регулярные выражения. Но, конечно, гибкость приходит со сложностью.
Я в порядке с регулярным выражением, просто у меня есть проблемы с производительностью
Большинство современных библиотек регулярных выражений фактически сканируют большие строки быстрее, чем простое сканирование (таким образом, простая реализация scanf). Это связано с тем, что большинство движков регулярных выражений используют алгоритм Бойера-Мура для буквального поиска с середины 80-х или начала 90-х годов. Конечно, вы также можете реализовать scanf с Бойером-Муром, но я не знаю, есть ли они. Я знаю, что С++ по умолчанию выполняет поиск строк медленнее, чем современные механизмы регулярных выражений, потому что С++ позволяет вам выбрать алгоритм Бойера-Мура в качестве альтернативного алгоритма для поиска строк. Альтернатива, не по умолчанию.
Вы пробовали использовать функцию
prompt()
?