Regex для сопоставления буквенно-цифровых символов в строке, содержащей URL - PullRequest
0 голосов
/ 02 февраля 2019

Учитывая несколько сценариев, как я могу сопоставить и извлечь буквенно-цифровые символы (и символы) в строке, содержащей URL-адреса?В настоящее время я использую Google Apps Script для извлечения обычного основного текста гиперссылки из сообщения цепочки Gmail, и я в основном хотел бы сопоставить и извлечь заголовок из некоторых строк следующим образом:

var scenario1 = "Testing: Stack Overflow Title 123? https://www.stackoverflow.com";

... в котором я хотел бы только вывести: "Testing: Stack Overflow Title 123?"

Вот еще один сценарий:

var scenario2 = "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com";

... снова, в котором я хотел бы тольковыходные данные: "Testing: Stack Overflow Title 123?"

Я попробовал следующее для первоначального тестирования, чтобы увидеть, содержит ли строка сначала URL-адрес (в котором я подтвердил, что регулярное выражение для соответствующих URL-адресов работает и выводит: https://www.stackoverflow.com), изатем проверяет, существует ли заголовок для его извлечения, но безрезультатно:

var scenario1 = "Testing: Stack Overflow Title 123? https://www.stackoverflow.com";
var scenario2 = "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com";
var urlRegex = /(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/;
var titleRegex = /^[a-zA-Z0-9_:?']*$/;
var containsUrl = urlRegex.test(element);
if (containsUrl) {
    var containsTitle = titleRegex.test(scenario1);
    if (containsTitle) { // No match, and doesn't run
      var title = titleRegex.exec(element)[0];
      Logger.log("title: " + title);
    }
}

По сути, я бы хотел шаблон Regex, который соответствует ВСЕМУ, но URL-адресам, если возможно

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Вы можете использовать .split() пробелы и .filter() результирующий массив, чтобы исключить элементы, которые начинаются с указанных протоколов или заканчиваются словом, затем точкой, затем словом и концом строки

const splitURL = s => s.split` `.filter(w => !/^\w+(?=:\/\/)|\w+\.\w+$/.test(w)).join` `;
 
var scenario1 = "Testing: Stack Overflow Title 123? https://www.stackoverflow.com";

var scenario2 = "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com";

console.log(splitURL(scenario1), splitURL(scenario2));
0 голосов
/ 02 февраля 2019

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

(?:^|\s+)((?:(?!:\/\/).)*)(?=\s|$)

Объяснение:

  • (?:^|\s) - совпадениялибо начало строки, либо один или несколько пробелов
  • ((?:(?!:\/\/).)*) - соответствует любому тексту, кроме того, который содержит ://, буквально идентифицируя его как URL
  • (?=\s|$) - положительный взгляд, чтобы обеспечитьза ним следует пробел или конец строки

Demo

Это соответствует и захватывает любой последовательный текст, кроме URL-адресов.Надеюсь, что это работает для вас.

Вот демонстрационный пример Javascript.

var arr = ['Testing1: Stack Overflow Title 123? https://www.stackoverflow.com','https://www.stackoverflow.com    Testing2: Stack Overflow Title xyz? https://www.stackoverflow.com Hello this is simple text ftp://www.downloads.com/']

for (s of arr) {
	var reg = /(?:^|\s+)((?:(?!:\/\/).)*)(?=\s|$)/g;
	match = reg.exec(s);
	while (match != null) {
		console.log(match[1])
		match = reg.exec(s);
	}
}

Кроме того, как я вижу, вы хотите ограничить количество символов в соответствующем заголовке, вы можете использовать свой набор символов [a-zA-Z0-9_:?' ] (в вашем наборе символов добавлено место, чтобытакже захватывая пробелы) вместо . в моем регулярном выражении и используйте следующее регулярное выражение, чтобы быть более точным во избежание захвата заголовка, содержащего непреднамеренные символы,

(?:^|\s+)((?:(?!:\/\/)[a-zA-Z0-9_:?' ])*)(?=\s|$)

Демонстрация с набором символов заголовка

0 голосов
/ 02 февраля 2019

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

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

\bTesting: .*?(?=\s*(?:https?|ftps?):\/\/)

const regexLookahead = /\bTesting: .*?(?=\s*(?:https?|ftps?):\/\/)/;
[
  "Testing: Stack Overflow Title 123? https://www.stackoverflow.com",
  "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com"
].forEach(s => console.log(s.match(regexLookahead)[0]));

Использование группы захвата, где ваше значение будет в первой группе захвата:

(\bTesting: .*?)\s*(?:https?|ftps?):\/\/

const regexGroup = /(\bTesting: .*?)\s*(?:https?|ftps?):\/\//;
[
  "Testing: Stack Overflow Title 123? https://www.stackoverflow.com",
  "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com"
].forEach(s => console.log(s.match(regexGroup)[1]));

Если вы хотите сохранить все, кроме URL, вы можете сопоставить их и заменить пустой строкой:

\s*(?:https?|ftps?):\/\/\S+

[
  "Testing: Stack Overflow Title 123? https://www.stackoverflow.com",
  "https://www.stackoverflow.com Testing: Stack Overflow Title 123? https://www.stackoverflow.com",
  "https://www.stackoverflow.com test https://www.stackoverflow.com test https://www.stackoverflow.com test",
  "https://www.stackoverflow.com test",
  "test https://www.stackoverflow.com"
].forEach(s => console.log(s.replace(/\s*(?:https?|ftps?):\/\/\S+/g, '').trim()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...