Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Логика регулярных выражений (https://javascript.ru/forum/events/29495-logika-regulyarnykh-vyrazhenijj.html)

Overflow 30.06.2012 13:00

Логика регулярных выражений
 
Товарищи форумчане! Помогите, пожалуйста, понять логику работы регулярки на данном примере:

На вход подается ссылка на картинку определенного формата. На выходе должна выйти ссылка без протокола и query_string.

Пример: подаем http://site.ru/folder/picture.jpg?query&string или https://site.ru/folder/picture.jpg
На выходе получаем site.ru/folder/picture.jpg

Код:
if(document.getElementById('element_input').value.toLowerCase().indexOf('://', 0) > -1){
	picture = document.getElementById('element_input').value.match(/\:\/\/(.+?)\.(jpg|jpeg|png|bmp|gif)/i);
}else{
	picture = document.getElementById('element_input').value.match(/(.+?)\.(jpg|jpeg|png|bmp|gif)/i);
}

// на выходе picture[1] + "." + picture[2]


Да, этот код рабочий, но.. можно его как-то усовершенствовать убрав поиск через indexOf и переместив его в само регулярное выражение?
Попытки вроде
picture = document.getElementById('element_input').value.match(/(?:\:\/\/)??(.+?)\.(jpg|jpeg|png|bmp|gif)/i);

возвращают picture[1] вместе с возможным ://, а так быть не должно (должна быть "чистая" ссылка на картинку).

Собственно вопросы:
1. Почему picture[1] захватывает ://?
2. Как это исправить?

Заранее спасибо!

Deff 30.06.2012 13:54

Overflow,
Приведите реальные примеры двух трёх входных строк и что желаем видеть на выходе

Overflow 30.06.2012 22:36

input: http://cs315420.userapi.com/v3154206...u-OE.jpg?ololo
output: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg

input: https://cs315420.userapi.com/v315420...?ololo&trololo
output: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg

input: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo
output: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg

input: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jPg
output: cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jPg

т.е. на входе любая ссылка на любую картинку в интернете. Ссылка обрабатывается и сохраняется, а протокол и всё, что после формата - откидываются.

Deff 30.06.2012 23:12

<script type="text/javascript">
function InputTST(select) {
 var str = document.getElementById(select).value;
 str2=str.replace(/\s*(?:http:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //
 if(RegExp["$2"]!='') return str2;
 return false;
}
</script>
<input size="73" id="element_input" type="text" value=" cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo" /> <button type="button" onclick="alert('\''+InputTST('element_input')+'\'')">Test</button>

Overflow 01.07.2012 01:36

Спасибо за ответ! Не подскажите, почему часть с http
str2=str.replace(/(?:http:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //

работает на ура, а с отслеживанием "://" без символов букв
str2=str.replace(/(?:\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //

"бракует" ("http://" помещается в $1, первая группировка её не видит)? Интересует именно почему :// игнорируются первым группированием, а если группировать http:// - то нет.

Deff 01.07.2012 02:17

Цитата:

Сообщение от Overflow
"бракует" ("http://" помещается в $1, первая группировка её не видит)? Интересует именно почему :// игнорируются первым группированием, а если группировать http:// - то нет.

Ничо не понял - приведите входные варианты и выходные

Может так ?
str2=str.replace(/(?:.*?:?\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //

devote 01.07.2012 10:37

Цитата:

Сообщение от Overflow
"бракует" ("http://" помещается в $1, первая группировка её не видит)? Интересует именно почему :// игнорируются первым группированием, а если группировать http:// - то нет.

потому что вы делаете replace а не match
var a = "http://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo";
alert( a.replace( /(?:http(?:s)?)?(?::\/\/)?(.*?\.(?:jpg|jpeg|png|bmp|gif)).*/gi, '$1' ) );

var a = "https://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo";
alert( a.replace( /(?:http(?:s)?)?(?::\/\/)?(.*?\.(?:jpg|jpeg|png|bmp|gif)).*/gi, '$1' ) );

var a = "://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo";
alert( a.replace( /(?:http(?:s)?)?(?::\/\/)?(.*?\.(?:jpg|jpeg|png|bmp|gif)).*/gi, '$1' ) );

var a = "cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo";
alert( a.replace( /(?:http(?:s)?)?(?::\/\/)?(.*?\.(?:jpg|jpeg|png|bmp|gif)).*/gi, '$1' ) );

Overflow 01.07.2012 12:20

devote, Deff, спасибо за ответы!


Цитата:

Сообщение от devote (Сообщение 185562)
потому что вы делаете replace а не match

Пример:
<script type="text/javascript">
function InputTST(select) {
 var str = document.getElementById(select).value;
str2=str.replace(/(?:.*\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2');
//str2=str.replace(/(?:\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2');

 if(RegExp["$2"]!='') return str2;
 return false;
}
</script>
<input size="73" id="element_input" type="text" value="https://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo" /> <button type="button" onclick="alert('\''+InputTST('element_input')+'\'')">Test</button>

Но ведь если убрать .* в первой группе регулярка будет работать только тогда, когда :// будут в начале строки. Почему так? Ведь я /^ в начале не указывал? Пример:
<script type="text/javascript">
function InputTST(select) {
 var str = document.getElementById(select).value;
//str2=str.replace(/(?:.*\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2');
str2=str.replace(/(?:\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2');

 if(RegExp["$2"]!='') return str2;
 return false;
}
</script>
<input size="73" id="element_input" type="text" value="https://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo" /> <button type="button" onclick="alert('\''+InputTST('element_input')+'\'')">Test</button>

Аналогично и с mathes (что я делаю не так?):
<script type="text/javascript">
function InputTST(select) {
 var str = document.getElementById(select).value;
//str2=str.replace(/(?:.*\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //
//str2=str.replace(/(?:\:\/\/)?(.*)\.(jpg|jpeg|png|bmp|gif).*$/ig,'$1.$2'); //
var matches = str.match(/(?:\:\/\/)?(.+)\.(jpg|jpeg|png|bmp|gif)/i);

return matches[2] ? (matches[1] + "." + matches[2]) : false;
}
</script>
<input size="73" id="element_input" type="text" value="https://cs315420.userapi.com/v315420616/2bf/V7iMAyfu-OE.jpg?ololo&trololo" /> <button type="button" onclick="alert('\''+InputTST('element_input')+'\'')">Test</button>

Deff 01.07.2012 13:23

Overflow,
У devote, правильный вариант, посколь я тещу лишь наличие расширение, а devote выдаёт строку - если есть и расширения и начальные варианты строки

nerv_ 01.07.2012 20:28

Цитата:

Сообщение от Overflow
Да, этот код рабочий, но.. можно его как-то усовершенствовать убрав поиск через indexOf и переместив его в само регулярное выражение?

Зачем регулярное выражение, если можно, как Вы уже обозначили "дешево и сердито"?


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