Обнаружение (непослушного или приятного) URL или ссылки в текстовой строке

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

Это также зависит от того, что вы хотите сделать. Вы хотите оптимизировать или ищете надежные гарантии того, что два экземпляра (или не являются) одной и той же функцией? (Если последнее, вы столкнетесь с вычислительной физикой, в том, что даже проблемы, столь же простые, как вопрос о том, могут ли две функции вычислять одну и ту же вещь, неразрешимы.)

С точки зрения спецификации, language spec обещает только, что результат вычисления (не вызывая) лямбда-выражения является экземпляром класса, реализующего целевой функциональный интерфейс. Он не дает никаких обещаний относительно идентичности или степени сглаживания результата. Это по дизайну, чтобы обеспечить максимальную гибкость реализации, чтобы предлагать лучшую производительность (так как lambdas может быть быстрее, чем внутренние классы, мы не привязаны к ограничению «должен создавать уникальный экземпляр», что внутренние классы.)

Так что, в принципе, спецификация не дает вам многого, кроме, очевидно, что два lambdas, которые являются ссылочными (==), собираются вычислить одну и ту же функцию.

С точки зрения реализации вы можете сделать еще несколько. Существует (в настоящее время может измениться) соотношение 1: 1 между синтетическими классами, которые реализуют лямбда, и местами захвата в программе. Таким образом, два отдельных бита кода, которые захватывают «x -> x + 1», могут быть сопоставлены с разными классами. Но если вы оцениваете одну и ту же лямбду на том же участке захвата и что лямбда не захватывает, вы получаете тот же экземпляр, который можно сравнить с эталонным равенством.

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

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

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

К сожалению, это трудно сделать (для несериализуемых lambdas, вы не можете получить всех компонентов этого) и недостаточно (поскольку два отдельно скомпилированных файла могут преобразовывать одну и ту же lambda в один и тот же функциональный тип интерфейса, и вы не смогли бы сказать.)

EG обсудила, следует ли предоставлять достаточную информацию, чтобы иметь возможность делать эти суждения, а также обсуждать, следует ли lambdas применять более выборочные equals / hashCode или более описательный toString. Вывод состоял в том, что мы не желали платить что-либо по стоимости исполнения, чтобы сделать эту информацию доступной для вызывающего абонента (плохой компромисс, наказывая 99,99% пользователей за то, что выгодно 0,01%).

Окончательный вывод о toString не был достигнут, но остался открытым для пересмотра в будущем. Однако по этому вопросу были высказаны хорошие аргументы в пользу обеих сторон; это не шлепанье.

37
задан Community 23 May 2017 в 11:55
поделиться

12 ответов

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

Я думаю, что ваша лучшая ставка будет на ДВУ. Существуют двухбуквенные нДВУ и сравнительно небольшой список (в настоящее время). Они должны начинаться с точки или с суффикса или какой-либо границы слова. Как отметили другие, это не будет идеальным. Нет никакого способа получить «покупать забавные фармацевтические препараты. Это», не отказываясь от законного «я попробовал снова. Это не работает» или подобного. Все это говорит, это было бы моим предложением:

[^\b]\.([a-zA-Z]{2}|aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel)[\b/]

Вещи, которые это получит:

Это, конечно, сломается, как только люди начнут запутывать свои URL, заменяя «.» с "точкой". Но, опять же, если предположить, что ваша цель - спамеры, если они начнут делать подобные вещи, их рейтинг кликов упадет еще на пару порядков до нуля. Множество людей, достаточно информированных, чтобы деобфусцировать URL, и множество людей, недостаточно информированных, чтобы посещать спам-сайты, я думаю, имеет крошечное пересечение. Это решение должно позволить вам обнаруживать все URL-адреса, которые можно копировать и вставлять в адресную строку, сохраняя при этом побочный ущерб на минимальном уровне.

Это, конечно, будет сломайте, как только люди начнут запутывать свои URL, заменяя «.» с "точкой". Но, опять же, если предположить, что ваша цель - спамеры, если они начнут делать подобные вещи, их рейтинг кликов упадет еще на пару порядков до нуля. Множество людей, достаточно информированных, чтобы деобфусцировать URL, и множество людей, недостаточно информированных, чтобы посещать спам-сайты, я думаю, имеет крошечное пересечение. Это решение должно позволить вам обнаруживать все URL-адреса, которые можно копировать и вставлять в адресную строку, сохраняя при этом побочный ущерб на минимальном уровне.

Это, конечно, будет сломайте, как только люди начнут запутывать свои URL, заменяя «.» с "точкой". Но, опять же, если предположить, что ваша цель - спамеры, если они начнут делать подобные вещи, их рейтинг кликов упадет еще на пару порядков до нуля. Множество людей, достаточно информированных, чтобы деобфусцировать URL, и множество людей, недостаточно информированных, чтобы посещать спам-сайты, я думаю, имеет крошечное пересечение. Это решение должно позволить вам обнаруживать все URL-адреса, которые можно копировать и вставлять в адресную строку, сохраняя при этом побочный ущерб на минимальном уровне.

com / ** questions / 700163 /

Это, конечно, сломается, как только люди начнут запутывать свои URL, заменяя «.» с "точкой". Но, опять же, если предположить, что ваша цель - спамеры, если они начнут делать подобные вещи, их рейтинг кликов упадет еще на пару порядков до нуля. Множество людей, достаточно информированных, чтобы деобфусцировать URL, и множество людей, недостаточно информированных, чтобы посещать спам-сайты, я думаю, имеет крошечное пересечение. Это решение должно позволить вам обнаруживать все URL-адреса, которые можно копировать и вставлять в адресную строку, сохраняя при этом побочный ущерб на минимальном уровне.

com / ** questions / 700163 /

Это, конечно, сломается, как только люди начнут запутывать свои URL, заменяя «.» с "точкой". Но, опять же, если предположить, что ваша цель - спамеры, если они начнут делать подобные вещи, их рейтинг кликов упадет еще на пару порядков до нуля. Множество людей, достаточно информированных, чтобы деобфусцировать URL, и множество людей, недостаточно информированных, чтобы посещать спам-сайты, я думаю, имеет крошечное пересечение. Это решение должно позволить вам обнаруживать все URL-адреса, которые можно копировать и вставлять в адресную строку, сохраняя при этом побочный ущерб на минимальном уровне.

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

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

19
ответ дан 27 November 2019 в 04:48
поделиться

Здесь уже есть отличные ответы, поэтому я не буду публиковать больше. Я дам пару замечаний. Во-первых, обязательно проверьте известные протоколы, все остальное может показаться непослушным. Как человек, чье хобби касается ссылок Telnet, вы, вероятно, захотите включить в свой поиск больше, чем http (s), но, возможно, захотите предотвратить, скажем, цель: или некоторые другие URL-адреса. Во-вторых, многие люди заключают свои ссылки в угловые скобки (gt / lt), например < http://theroughnecks.net > или в скобки «(url)», и нет ничего хуже, чем щелкнуть ссылка, а закрывающая> или) идет вместе с остальной частью URL-адреса.

P.S. извините за саморегулирующиеся заглушки;)

1
ответ дан 27 November 2019 в 04:48
поделиться

Мне нравится ответ capar лучший на данный момент, но работа со шрифтами Unicode может быть немного чреватой, так как старые браузеры часто показывают забавную вещь или маленькая коробочка ... и расположение U + 05B4 немного странно ... для меня это выглядит вне труб здесь | ִ | даже если это между ними.

Есть удобный & миддот; (·) Хотя, который ломает вырезать и вставить таким же образом. Его вертикальное выравнивание можно исправить с помощью , например:

stackoverflow · com

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

это появляется вне труб здесь | ִ | даже если это между ними.

Есть удобный & миддот; (·) Хотя, который ломает вырезать и вставить таким же образом. Его вертикальное выравнивание можно исправить с помощью , например:

stackoverflow · com

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

это появляется вне труб здесь | ִ | даже если это между ними.

Есть удобный & миддот; (·) Хотя, который ломает вырезать и вставить таким же образом. Его вертикальное выравнивание можно исправить с помощью , например:

stackoverflow · com

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

который ломает вырезать и вставить таким же образом. Его вертикальное выравнивание можно исправить с помощью , например:

stackoverflow · com

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

который ломает вырезать и вставить таким же образом. Его вертикальное выравнивание можно исправить с помощью , например:

stackoverflow · com

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

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

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

s/\b\.\b/<sub>&middot;<\/sub>/g

Другой вариант это вставить какой-то объект нулевой ширины рядом с подозрительными точками, но такие вещи, как & zwj; и & zwnj; и & ampzwsp; не похоже на работу в FF3.

1
ответ дан 27 November 2019 в 04:48
поделиться

Рассмотреть вопрос о включении OWASP AntiSAMY API ...

1
ответ дан 27 November 2019 в 04:48
поделиться

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

Однако я могу с большой уверенностью сказать, что если вы действительно хотите Чтобы победить спамеров, лучший способ сделать это - использовать JavaScript. Отправьте кусок JavaScript, который выполняет некоторые вычисления, и повторите вычисления на стороне сервера. JavaScript должен скопировать результат вычисления в скрытое поле, чтобы при отправке комментария также передавался результат вычисления. Проверьте на стороне сервера, что расчет верен. Единственный способ обойти эту технику - спаммеры могут вручную вводить комментарии или запускать движок JavaScript только для вас. Я использовал эту технику, чтобы уменьшить количество спама на моем сайте со 100+ в день до одного или двух в год. Теперь единственный спам, который я когда-либо получаю, вводится людьми вручную. Странно получать спам по теме.

1
ответ дан 27 November 2019 в 04:48
поделиться

Конечно, вы понимаете, что если спамеры решат использовать tinuyrl или подобные сервисы, чтобы сократить свои URL, ваша проблема только ухудшится , Возможно, вам придется написать некоторый код для поиска реальных URL-адресов в этом случае, используя такой сервис, как TinyURL декодер

1
ответ дан 27 November 2019 в 04:48
поделиться

Так как вы в первую очередь ищете приглашения для копирования и вставки в адресную строку браузера, возможно, стоит взглянуть в коде, используемом в браузерах с открытым исходным кодом (таких как Chrome или Mozilla), чтобы решить, является ли текст, введенный в «эквивалент адресной строки», поисковым запросом или попыткой навигации по URL.

3
ответ дан 27 November 2019 в 04:48
поделиться

Ну, очевидно, низко висящие фрукты - это вещи, которые начинаются с http: // и www. Попытка отфильтровать такие вещи, как «www. G mail. Com», приводит к интересным философским вопросам о том, как далеко вы хотите зайти. Вы хотите сделать следующий шаг и отфильтровать «www dot gee mail dot com»? Как насчет абстрактных описаний URL, таких как «Аббревиатура для всемирной паутины, за которой следует точка, за которой следует буква g, за которой следует слово mail, за которым следует точка, заканчивающаяся сокращением TLD для коммерческого использования».

Важно провести черту, какие вещи вы собираетесь пытаться отфильтровать, прежде чем продолжать пытаться разработать свой алгоритм. Я думаю, что линия должна быть проведена на уровне, где "gmail.com" считается URL, но "Gmail. ком" не является. В противном случае вы, вероятно, получите ложные срабатывания каждый раз, когда кто-то не сможет использовать первую букву в предложении.

4
ответ дан 27 November 2019 в 04:48
поделиться

Я знаю, что это не поможет с текстом авто-ссылки, но что если вы будете искать и заменять все периоды полной остановки с символом, который выглядит как то же самое, например, символом юникода для точки иврита hiriq (U + 05B4)?

Следующий абзац является примером:

Это может сработать ִ Период выглядит несколько странно, но все еще читаемо ִ Преимущество, конечно, заключается в том, что любой, кто копирует и вставляет www ִ google ִ com, не станет слишком далеко ִ:)

6
ответ дан 27 November 2019 в 04:48
поделиться

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

Если ваша цель - просто отфильтровывать спам из комментариев, то вы можете подумать о байесовском ] фильтрация. Он оказался очень точным для пометки электронной почты как спама, он может сделать то же самое для вас, в зависимости от объема текста, который вам нужно отфильтровать.

6
ответ дан 27 November 2019 в 04:48
поделиться
13
ответ дан 27 November 2019 в 04:48
поделиться

Пинговать возможный URL

Если вы не возражаете против небольшого вычисления на стороне сервера, как насчет этого?

urls = []
for possible_url in extracted_urls(comment):
    if pingable(possible_url):
       urls.append(url)  #you could do this as a list comprehension, but OP may not know python

Здесь:

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

  2. pingable фактически использует системный вызов, чтобы определить, существует ли имя хоста в сети. Вы могли бы иметь простую оболочку для анализа вывода команды ping.

    [ramanujan: ~ / base] $ ping -c 1 www.google.com

    PING www.l.google.com (74.125.19.147): 56 байтов данных 64 байта из 74.125.19.147: icmp_seq = 0 ttl = 246 время = 18,317 мс

    --- www.l.google.com статистика пинга --- 1 пакет передан, 1 пакет получен, 0% потеря пакета туда-обратно min / avg / max / stddev = 18,317 / 18,317 / 18,317 / 0,000 мс

    [ramanujan: ~ / base] $ ping -c 1 fooalksdflajkd.com

    ping: не удается разрешить fooalksdflajkd.com: Неизвестный хост

Недостатком является то, что если хост выдает 404 вы его не обнаружите, но это довольно неплохой первый шаг - лучший способ проверить, является ли адрес веб-сайта, - попытаться перейти на него. Вы также можете попробовать wget'ing этот URL, но это более тяжелый вес.

2
ответ дан 27 November 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: