Регулярное выражение Javascript: сопоставить что-либо до чего-то (если оно существует) - PullRequest
16 голосов
/ 21 декабря 2011

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

Я пытаюсь использовать одно решение для 3 типов строк

  • "45%", ожидаемый результат: "45"
  • "45", ожидаемый результат: "45"
  • "", ожидаемый результат: ""

Что я пытаюсь (пусть строка будет str):

str.match(/(.*)(?!%*)/i)[1]

Это звучит в моей голове как "сопоставить любой экземпляр чего-либо вплоть до"% ", если он найден, или просто сопоставить что-либо"

В голове пожарного это звучит как "просто сопоставь что-либо и полностью игнорируй негативную перспективу". Также, чтобы сделать это ленивым - (.*)? - не похоже.

Давайте на секунду забудем, что в этой конкретной ситуации я сопоставляю только числа, так что /\d*/ подойдет. Я пытаюсь понять общее правило, чтобы применить его в любое время.

Кто-нибудь был бы так любезен, чтобы помочь мне?

Ответы [ 5 ]

26 голосов
/ 21 декабря 2011

Как насчет более простого

str.match(/[^%]*/i)[0]

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


Редактировать: Если необходимо выполнить синтаксический анализ до </a>, то вы можете проанализировать последовательность символов pf, с последующим </a>, а затем отбросить </a>, что означает, что вы должны использовать положительный прогнозный вместо отрицательного.

str.match(/.*?(?=<\/a>|$)/i)[0]

Это означает: лениво сопоставлять ноль или более символов до достижения </a> или конца строки.

Обратите внимание, что *? - это один оператор, (.*)? - это не то же самое, что .*?.

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

6 голосов
/ 21 декабря 2011

Я думаю, это то, что вы ищете:

/(?:(?!%).)*/

. соответствует любому символу, но только после того, как отрицательный символ (?!%) подтверждает, что символ не %. Обратите внимание, что когда часовым является отдельный символ, такой как %, вы можете использовать вместо него класс отрицанных символов, например:

/[^%]*/

Но для многосимвольного стража, такого как </a>, вы должны использовать осторожный подход:

/(?:(?!</a>).)*/i

Это на самом деле говорит: «Совпадение нуля или более символов по одному за раз, но если следующий символ оказывается началом последовательности </a> или </A>, остановитесь, не потребляя его».

3 голосов
/ 21 декабря 2011

Самый простой способ с точной строкой поиска - пропустить регулярные выражения и просто использовать indexOf, например ::

// String to be searched
var s = "Here is a <a>link</a>."

// String to find
var searchString = "</a>";

// Final match
var matched = "";

var c = s.indexOf(searchString);
if (c >= 0)
{
    // Returns the portion not including the search string;
    // in this example, "Here is a <a>link". If you want the
    // search string included, add the length of the search
    // string to c.
    matched = s.substring(c);
}
1 голос
/ 21 декабря 2011

Я просто написал это именно так, как вы сказали:

str.match(/(^[^%]*$)|^([^%]*)%.*/i)

Это будет соответствовать любой строке без «%» или первой части строки, содержащей%. Вы должны получить результат из 1-й или 2-й группы.

РЕДАКТИРОВАТЬ: Это именно то, что вы хотите ниже

str.match(/(?:^[^%]*$)|^(?:[^%]*)(?=%)/)
  • ?: Удаляет все группировки
  • ? = - это предвидение, чтобы увидеть, содержит ли строка%
  • и [^%] соответствует любому символу, который не является%

так что чтение регулярного выражения соответствует любой строке, которая не содержит%, ИЛИ (в противном случае соответствует) всем символам перед первым%

0 голосов
/ 21 декабря 2011

для совпадения с 45, 45% и любым числом любой длины используйте это (182%, 18242 и т. Д.)

str.match(/([0-9]+)([%]?)/)[1];

, если вам нужно сопоставить пустую строку, также включите ее как ^ $ , примечание соответствует ("...") [1] будет неопределенным для пустой строки , поэтому вам нужно будет проверить совпадение, а затем проверить [0] или посмотреть, если [1] не определено.

str.match(/([0-9]+)([%]?)|^$/)

, если вам нужно точно сопоставить две цифры, используйте {2,2} , чтобы закрепить выражение между символами начала и конца строки: " ^ (exp) $"

str.match(/^([0-9]{2,2})([%]?)$/)[1];
...