LINUX.ORG.RU

Регулярка для нахождения в тексте более пяти URL - как?

 ,


0

3

Есть текст, в котором могут быть прописаны от 0 до бесконечности URL.

Нужно, чтобы PCRE регулярка сработала в случае, есть количество URL больше 5.

Я пробую так:

(https?:\/\/.*?){5,}

Но такое впечатление, что квантор {5,} не применяется к группе в скобках.

Как правильно написать выражение?

★★★★★

а как эти url разделяются в тексте?

В этой re неоднозначно описан конец url. Просле ".*?" нужно какой-то разделитель.

vel ★★★★★
()

а регулярка урл вообще детерминирована? Например не такой уж и баян, что полная регулярка имейла занимает более 3-х страниц текста мне кажется.

anonymous
()

Оно не так делается:

/^(?=.{5,})https?:\/\/\S+$/.test('http://a')
true
/^(?=.{<минимальная_длина>,<максимальная_длина>})<точное_регулярное_выражение>$/
tz4678 ★★
()
Последнее исправление: tz4678 (всего исправлений: 1)

Я бы убрал «.*?» (по дефолту регулярки greedy и оно заматчит от первого «http://» и до конца строки; а если отключить жадность, то и вообще смысла нет), и сделал что-то типа такого (псевдокод): findAll(«http://»).count > 5.

dimgel ★★★★★
()
Последнее исправление: dimgel (всего исправлений: 2)

Ну и как работают твои «регулярки» если в тексте юникод например иероглифы?

bhfq ★★★★★
()
Ответ на: комментарий от vel

а как эти url разделяются в тексте?

Как угодно. Могут быть друг за другом, могут быть на отдельных строках, между ними могут быть различные символы.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от tz4678

Оно не так делается:
/^(?=.{5,})https?:\/\/\S+$/.test('http://a')

true

/^(?=.{<минимальная_длина>,<максимальная_длина>})<точное_регулярное_выражение>$/

Ты ничего не путаешь?

{n,m} — возможно кол-во вхождений _предшествующего_ символа от n до m

А ты рассказываешь что надо задом-наперед.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

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

tz4678 ★★
()
Ответ на: комментарий от tz4678

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

Так как этот способ работает?

Приведи регулярку, текст и результат. А то в этой дискуссии только ты что-то утверждаешь, а противоположная сторона не может в этом убедиться. Поэтому передачи знания не происходит.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Ты дурной чтоли? Ты во-первых флаги не включил.

/^(?=.{5,})https?:\/\/\S+$/gm

А во-вторых хз для чего ты эту регулярку используешь. В том же sed она работать не будет, потому как там регулярки не поддерживают просмотров назад/вперед. И еще есть отличия в реализации в разных языках программирования, например, тот же js не поддерживает просмотр назад.

tz4678 ★★
()
Ответ на: комментарий от tz4678

Самая простая регулярка для проверки урлов будет выглядеть примерно так:

/^https?:\/\/(\S+\.){1,}\S+$/.test('http://проститутки.рф')
true
/^https?:\/\/(\S+\.){1,}\S+$/.test('http://я у мамы программист')
false
/^https?:\/\/(\S+\.){1,}\S+$/.test('http://www.site.ru')
true

Если ты хочешь в тексте подсвечивать ссылки, то на js оно будет выглядеть примерно так:

'http://накуй.сру тест'.replace(/https?:\/\/(\S+\.){1,}\S+/, '<a href="$&">$&</a>')
"<a href="http://накуй.сру">http://накуй.сру</a> тест"
tz4678 ★★
()
Последнее исправление: tz4678 (всего исправлений: 4)

У тебя проблема в том, что точка не матчит символ новой строки. На regex101 это регулируется флагом s, например. Ну или можно явно:

(https?:\/\/(.|\n)*?){5,}
deadNightTiger ★★★★★
()
Ответ на: комментарий от deadNightTiger

у него вообще идиотская идея ограничивать длину искомой строки по нижней границе (нужно по верхней). тем более «http://» уже 7 символов, а у него 5 минимум. твой пример не рабочий.

// Это типа правильно
/(https?:\/\/(.|\n)*?){5,}/.test('http://http://http://http://http://')
true
tz4678 ★★
()

Зачем тебе лишний раз перебирать значения? Ставь фиксированное число, если 5 - минимальный порог.

Вот так должно работать: (https?://.*){5}

anonymous
()
Ответ на: комментарий от tz4678

Перечитай ОП внимательнее, он это и хочет (матчить, если https?:// встречается пять или больше раз в рамках всего текста). Про длину этих матчей никто не говорил.

deadNightTiger ★★★★★
()
Ответ на: комментарий от tz4678

Ты дурной чтоли? Ты во-первых флаги не включил. А во-вторых хз для чего ты эту регулярку используешь. В том же sed она работать не будет, потому как там регулярки не поддерживают просмотров назад/вперед. И еще есть отличия в реализации в разных языках программирования, например, тот же js не поддерживает просмотр назад.

Я же в топике написал PCRE.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от vodz

Говорят-то правильно, но никто кроме вас не сказал как правильно это сделать.

Xintrea ★★★★★
() автор топика

https: https: https: https:

ТС, а http: ты уже урлом не считаешь? Библиотека Мошкова, например.

hobbit ★★★★★
()
Ответ на: комментарий от vodz

Ой, всё! Ошибся. Приношу извинения.

Осталось выяснить, нужны ли ТСу для его задачи ссылки на ftp, например. Строго говоря, это тоже URLы, и они тоже могут встречаться в рандомном тексте…

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от vodz

Зачем «окончание»? Регулярка срабатывает как с ним, так и без него. Ему же нужно только определить, что URL’ов в тексте пять штук.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Зачем «окончание»?

По определению нежадности. Как оно будет срабатывать без окончания зависит от реализации библиотеки. Для PCRE проверять лень, поверим ТСу, а на TRE-regex оно останвливается на http:// внезависимости от имеющегося продолжения.

vodz ★★★★★
()
Ответ на: комментарий от vodz

останвливается на http:// внезависимости от имеющегося продолжения.

Имеешь в виду http:// у последнего URL? Если да, то в чём проблема-то?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Если да, то в чём проблема-то?

Наверное в том, что это не то, что надо? Если мне надо было то, я бы так и написал http:// без всяких звездочек на конце.

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

Я думал, что тут проблему ТС’а обсуждают.

Именно, моё решение его полностью удовлетворило, а вам как всегда захотелось поперечить не по делу.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

моё решение его полностью удовлетворило

Мне это не особо интересно. ТС своеобразен. Мне интересна регулярка и вопрос поиска «окончания».

как всегда

Мда…

не по делу

Объясни мне, пожалуйста, для каких входных данных (https?://.*?){5,}(\s|$) найдёт факт наличия пяти URL, а (https?://.*?){5,} не найдёт.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Мне это не особо интересно.

Вы виляете, то вы пеклись о ТСе, то вдруг не интересен. Некрасиво.

Объясни мне

Объясняю, указание нежадного квалификатора без окончания превращает regex в мусор. Не надо писать мусор.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вы виляете, то вы пеклись о ТСе, то вдруг не интересен. Некрасиво.

Мне интересна задача.

указание нежадного квалификатора без окончания превращает regex в мусор

Пример-то будет? А то ты заявляешь, что виляю я, а виляешь сам.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Пример-то будет?

Пример тут в каждом сообщении этой темы. Начиная с третьего коммента дано правильное решение даже по книжному. Не согласны — можете идти править книжки.

А то ты заявляешь, что виляю я, а виляешь сам.

Ты облажался и виляешь. Что непонятного в том, что .*? без окончания просто мусор? Без него получается ровно тоже и без видимых затруднений в чтении и парсинга в голове без проб методом тыка.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Пример тут в каждом сообщении этой темы.

Я просил пример входных данных. Из всех сообщений есть только два с примерами входных данных. Один — «http://http://http://http://httphttp://» и ещё один от ТС’а в ссылке на regex101. Оба примера матчатся и регуляркой ТС’а и твоей регуляркой. Разницы нет.

Ты облажался и виляешь.

В чём? o_O
Я же вопросы задавал. Как можно облажаться, задавая вопросы?

Что непонятного в том, что .*? без окончания просто мусор?

Ты pcrepattern читал? Там в точности написано, что для PCRE означает .*?: «if a quantifier is followed by a question mark, it ceases to be greedy, and instead matches the minimum number of times possible». Если .*? будет в конце, он сматчит ровно ноль символов, потому что ноль — минимально возможное. Какой ещё «мусор»? Что за бред ты несёшь?

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Если .*? будет в конце,

Вы упорно добиваетесь игнора? Под мусором понимается что-то ненужное. То есть указание .*? в конце без окончания просто мусорное. Можете выбирать: либо вы прекрасно это поняли, но как всегда хотите оказаться правым не смотря на то, что облажались, либо просто тупы. Оба варианта никакого желания общаться не вызывает.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от vodz

Вы упорно добиваетесь игнора?

Не надо пугать меня игнором. Мне же лучше будет, если ты не будешь пытаться мне отвечать.

Я думал, что и правда есть какой-то момент, который я не понимаю, но от тебя внятного ответа не дождёшься. Ты настолько упёртый, что создаёшь ощущение тупого, как пробка. Конечно, есть шанс, что ты понимаешь, в чём дело, но самомнение не позволяет тебе признать, что для решаемой задачи разницы не будет. В пользу этого сценария говорят твоё упорное нежелание привести пример входных данных и попытки уйти от прямых вопросов.

либо вы прекрасно это поняли, но как всегда хотите оказаться правым не смотря на то, что облажались, либо просто тупы.

Забавно, но то же самое я могу сказать о тебе. Только я могу привести цитаты релевантных мест документации, а ты почему-то нет.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я думал, что и правда есть какой-то момент, который я не понимаю,

Ну дык. Влезли в топик с реальной проблемой, которая возникла у ТСа в ввиду чтения документации по диагонали и делаете вид, что у него там нет проблемы, хотя она очевидна. И только потому, что даже не «кто-то в Интернете не прав», а просто выпендриться, что для входных данных http://.*http://.*http://.*http://.*http:// оно даже работает. Охренеть как умно.

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

Ваше виляние тупо, как пробка. Потому таки вы добились.

Мне же лучше будет,

Почитайте на досуге по психологии что-нибудь. Уверяю, это не греет, как только пройдёт первый порыв.

vodz ★★★★★
()
Ответ на: комментарий от vodz

хотя она очевидна

Настолько очевидна, что описать ты её не осилил.

Почитайте на досуге по психологии что-нибудь. Уверяю, это не греет, как только пройдёт первый порыв.

facepalm

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.