Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Создание строки по регулярному выражению (https://javascript.ru/forum/misc/51983-sozdanie-stroki-po-regulyarnomu-vyrazheniyu.html)

2chan 28.11.2014 17:34

Создание строки по регулярному выражению
 
Не нашёл ничего подобного. Есть ли юзерские функции для создание строки по регулярному выражению?

danik.js 28.11.2014 17:54

Поясни.

tsigel 28.11.2014 18:00

Так чтоли?)))
alert(/a{,3}/.toString())

2chan 28.11.2014 18:11

tsigel,
Нет. Есть регулярное выражение. Нужна функция, которая создаст строку, которая, при тесте, даёт совпадение.
Пример
var a = /\w/;
создаст строку, в которой есть латинские буквы, цифры и знак подчёркивания.
var a = /\W/;
создаст строку, в которой нет символов лат. алфавита, цифр и знака подчёркивания.

tsigel 28.11.2014 18:16

2chan,
Очень похоже на создания бота для регистрации где-либо)

Не думаю что есть такие готовые скрипты.

danik.js 28.11.2014 18:24

Думаю нужно найти реализацию машины регулярных выражений на требуемом тебе языке (JS?), и уже дальше думать.

Яростный Меч 28.11.2014 18:26

Видимо, придется писать самостоятельно.
"конечные автоматы" и всё такое. на первый взгляд нечего сверхестественного нет.

2chan 28.11.2014 18:29

tsigel,
А так-же генерации пассов, создания валидных случайных имён... В общем, много для чего.

krutoy 28.11.2014 18:32

Цитата:

Сообщение от Яростный Меч
на первый взгляд

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

Яростный Меч 28.11.2014 18:49

Цитата:

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

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

а ещё бывают регексы с lookahead, причем последних может быть несколько (и некоторые из них отрицательные). вот тут да, суровый паззл, головоломный..

danik.js 28.11.2014 19:03

Странное чувство. Зашел в trending гитхаба

И первой же строкой идет вот такая вот штуковина:
JavaScript Regular Expression Parser & Visualizer. http://jex.im/regulex/

krutoy 28.11.2014 22:48

danik.js,
В чем же странность твоего чувства? Какое отношение парсер, а, тем-более, "visualizer" имеют к генерации строк по регекспу?

danik.js 29.11.2014 06:31

Да? А мне показалось что все очевидно. По крайней мере я тут же прикинул план решения.
Видимо у тебя с этим трудности.

krutoy 29.11.2014 07:41

danik.js,
вот тебе регулярное выражение f.o
вот тебе его парсер /f\.o/
сгенерируй мне выходные слова

danik.js 29.11.2014 10:33

Цитата:

Сообщение от krutoy
сгенерируй мне выходные слова

Нахуй слова, когда тс просит первый подходящий вариант?
И как ты себе представляешь генерацию всех вариантов для регулярки x* ?

danik.js 29.11.2014 10:38

<script src="http://libs.useso.com/js/require.js/2.1.11/require.min.js"></script>
<script>
	require.config({
		baseUrl: "http://jex.im/regulex",
	});
	require(['dest/parse'], function(parse) {
		var re = 'krutoy.лох';
		var root = parse(re);

		alert(generateMatchingString(root.tree));
	});

	var generateNode = {
		exact: function(node) {
			return node.chars;
		},
		dot: function(node) {
			return '*';
		},
		choice: function(node) {
			return generateMatchingString(node.branches[0]);
		}
	};

	function generateMatchingString(tree) {
		var chunks = tree.map(function(node){
			return generateNode[node.type](node);
		});
		return chunks.join('');
	}

</script>


Узлы backref, repeat, empty, charset и тд предлагаю реализовать топик-стартеру. Либо раздел Работа.

krutoy 29.11.2014 10:56

Цитата:

Сообщение от danik.js
dot: function(node) {
return '*'

А это чо значит? Ты за идиотов тут всех держишь? Может вот так сразу
alert("krutoy.loh".replace(/\./, "*"))

?
Или ты сам идиот?

krutoy 29.11.2014 11:01

Цитата:

Сообщение от danik.js
как ты себе представляешь генерацию всех вариантов для регулярки x*

Это ты что-то там представлял. Видимо, начинает допирать.

danik.js 29.11.2014 12:06

Цитата:

Сообщение от krutoy
Может вот так сразу

Ну хуле, давай, покажи как таким макаром генерировать повторы, бэкрефы, лукахеды, и прочую хуиту :D

danik.js 29.11.2014 12:12

Короче, ди нах троль. ТС поставил задачу, я показал как ее можно решить. Можешь дальше ссаться кипятком.

krutoy 29.11.2014 12:20

danik.js,
Все что ты показал -- это тупая подстановка.
Цитата:

Сообщение от danik.js
я показал как ее можно решить.

Ты не показал, а доказал, доказал в очередной раз, что ты клоун.

krutoy 29.11.2014 12:23

danik.js,
Ты вообще собственно, сделал через жопу то, что и так можно сделать, причем тупейшим образом. Никакой генерации я в твоем тупорылом коде не увидел. Ты, видно, вообще не представляшь, что тако генерация. Слив засчитан.

krutoy 29.11.2014 12:27

Цитата:

Сообщение от danik.js
генерировать повторы, бэкрефы, лукахеды

Ты хоть понимаешь, что ты несешь??? Сгенрируй уж тогда alert, чтоли, генератор бреда херов.

danik.js 29.11.2014 12:41

Пример генерации номера телефона по шаблону:
<script src="http://libs.useso.com/js/require.js/2.1.11/require.min.js"></script>
<script>
	require.config({
		baseUrl: "http://jex.im/regulex",
	});
	require(['dest/parse'], function(parse) {
		var re = '\\+7 \\(\\d{3}\\) \\d{3}\\-\\d{2}\\-\\d{2}';
		var root = parse(re);
 
		alert(generateMatchingString(root.tree));
	});

	var randomClass = {
		'd': function() {
			return Math.round(Math.random() * 9);
		}
	}
 
	var generateNode = {
		exact: function(node) {
			return node.chars;
		},
		dot: function(node) {
			return String.fromCharCode(65 + Math.round(Math.random() * 25));
		},
		choice: function(node) {
			return generateMatchingString(node.branches[0]);
		},
		repeat: function(node) {
			var result = [];
			for (var i = 0; i < node.repeat.min; i++) {
				result.push(generateNode[node.type](node));
			}
			return result.join('');
		},
		charset: function(node) {
			if (node.classes) {
				return randomClass[node.classes[0]]();
			}
		}
	};
 
	function generateMatchingString(tree) {
		var chunks = tree.map(function(node){
			if (node.repeat)
				return generateNode.repeat(node);
			else
				return generateNode[node.type](node);
		});
		return chunks.join('');
	}
 
</script>

krutoy 29.11.2014 12:45

danik.js,
Ну, это еще куда ни шло, вроде похоже на правду, да.

danik.js 29.11.2014 13:48

Добавил поддержку символьных классов (кроме исключающих) и групп.
<meta charset="utf-8">
<form id="form">
	<p><label>Регулярка:</label><input name="input"> <button name="run" type="button">Герерировать</button></p>
	<p><label>Результат:</label><input name="output"></p>
</form>
<script src="http://libs.useso.com/js/require.js/2.1.11/require.min.js"></script>
<script>
	require.config({
		baseUrl: "http://jex.im/regulex",
	});
	require(['dest/parse'], function(parse) {
		var form = document.forms.form;
		form.run.onclick = function() {
			var root = parse(form.input.value);
			form.output.value = generateMatchingString(root.tree);
		}
	});

	var charClasses = {
		'd': {ranges: ['09']},
		's': {chars: ' \f\n\r\t\v'},
		'w': {ranges: ['09', 'az', 'AZ'], chars: '_'}
	};

	function rangeToChars(range) {
		var chars = '';
		for (var i = range.charCodeAt(0); i < range.charCodeAt(1); i++) {
			chars += String.fromCharCode(i);
		}
		return chars;
	}

	function classToChars(charClass) {
		var chars = '';
		var derivedChars = charClasses[charClass];
		if (derivedChars.chars)
			chars += derivedChars.chars;
		if (derivedChars.ranges)
			chars += derivedChars.ranges.map(rangeToChars).join('');
		return chars;
	}

	function charSet(chars, classes, ranges) {
		chars += classes.map(classToChars).join('');
		chars += ranges.map(rangeToChars).join('');
		return chars;
	}

	var generateNode = {
		exact: function(node) {
			return node.chars;
		},
		dot: function(node) {
			return String.fromCharCode(65 + Math.round(Math.random() * 25));
		},
		choice: function(node) {
			return generateMatchingString(node.branches[Math.round(Math.random()*node.branches.length)]);
		},
		repeat: function(node) {
			var result = [];
			for (var i = 0; i < node.repeat.min; i++) {
				result.push(generateNode[node.type](node));
			}
			return result.join('');
		},
		charset: function(node) {
			var chars = charSet(node.chars, node.classes, node.ranges);
			return chars[Math.round(Math.random()*chars.length)];
		},
		group: function(node) {
			return generateMatchingString(node.sub);
		}
	};

	function generateMatchingString(tree) {
		var chunks = tree.map(function(node){
			if (node.repeat)
				return generateNode.repeat(node);
			else
				return generateNode[node.type](node);
		});
		return chunks.join('');
	}
 
</script>

danik.js 29.11.2014 13:54

Цитата:

Сообщение от krutoy
Ну, это еще куда ни шло, вроде похоже на правду, да.

Ну теперь то у тебя не осталось иллюзий по поводу того, кто из нас идиот?

Яростный Меч 29.11.2014 16:09

А всё-таки, что делать с несколькими lookahead в регексе?
/...(?=...)(?=...)(?!...)/
и т.д.

danik.js 29.11.2014 16:20

Цитата:

Сообщение от Яростный Меч
А всё-таки, что делать с несколькими lookahead в регексе?

Это принципиально нерешаемая проблема или что? Я не собираюсь больше дописывать ничего.

ruslan_mart 29.11.2014 16:47

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

Лучше уж написать ф-цию, которая будет понимать что и где генерировать, причём чтобы ф-ция использовала какой-нибудь свой "синтаксис", типо:

function genStr(pattern) {
   //...
}

alert( genStr('$d5$w3$W3$d[0-5]6') ); //19435fgtMZP302213

$Type[from-to]N

Где:
- Type - тип генерируемого значения (n - цифра, w - любая латинская буква в нижнем регистре, W - любая латинская буква в верхнем регистре).
- [form-to] - допустимые значения (от - до).
- N - количество генераций значения.

Например:
$d - сгенерирует строку из одного случайно числа
$d5 - сгенерирует строку из 5 случайных цифр
$d[3-7] - сгенерирует строку из одного случайного числа в диапазоне от 3 до 7 включительно.
$d[4-9]3 - сгенерирует строку из трёх случайных чисел в диапазоне от 4 до 9 включительно.
$w10 - сгенерирует строку из 10 случайных букв латинского алфавита в нижнем регистре.
$W[a-f]5 - сгенерирует строку из 5 случайных букв в диапазоне от "a" до "f", нижнем регистре латинского алфавита.
$w$d3$w5 - "случайная буква н.р. + 3 случайные цифры + 5 случайных букв н.р."


Ну это так, как идея. Можно конечно всё это дело расширить или вообще сделать по другому. :)

danik.js 29.11.2014 16:57

Поздравляю, ты изобрел регулярку, только с урезанными возможностями и немного другим синтаксисом )
Вот только парсер регулярок уже написан, а парсер твоего синтаксиса - нет.

Яростный Меч 29.11.2014 18:07

Цитата:

Сообщение от danik.js (Сообщение 343437)
Это принципиально нерешаемая проблема или что? Я не собираюсь больше дописывать ничего.

Загвоздка вот в чем: в каждом лукахеде содержится свой регекс, и надо получить такую строку, которая соответствует всем регексам из положительных лукахедов и в то же время не матчится ни одним из отрицательных. А это уже "совсем другая история".


Часовой пояс GMT +3, время: 06:10.