2010-12-14 3 views
1

мне интересно, если есть способ, имеющий этотRegex найти последний маркер на строку

var string = "foo::bar" 

Чтобы получить последнюю часть строки: "bar" используя только регулярное выражение.

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

-

UPDATE

Возможно, некоторые примеры сделает вопрос более ясным.

var st1 = "foo::bar::0" 
match should be 0 

var st2 = "foo::bar::0-3aab" 
match should be 0-3aab 

var st3 = "foo" 
no match should be found 
+0

в качестве разделителя, я хочу, чтобы все после того, как последний раздел «::» мог бы состоять в том, что после «::» у меня есть другой тип символа, числа и т. д. – jpabluz

+0

Может ли последний токен содержать ':'? Если да, может ли это быть 'foo ::: bar', и как вы справитесь с этим? – Kobi

ответ

8

Вы можете использовать отрицательный предпросмотр:

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

Результат будет находиться в захвате.

Другой подход:

/^.*::(.*)$/ 

Это должно работать, потому что .* матчи с жадностью, поэтому :: будут соответствовать последней вхождения этой строки.

+0

И если у вас есть пробел в конце или может иметь или не иметь завершающий пробел, попробуйте вместо этого «\\ w + \\ s * $». –

+0

Это не сработает для моих примеров, в первом примере оно будет соответствовать «bar :: 0». – jpabluz

+0

Это не сработает - '*' жадный, и, например, будет соответствовать 'bar :: 0-3aab' в' foo :: bar :: 0-3aab'. –

2

Просто

/::(.+)$/ 

Вы не можете использовать lookaheads, если вы точно не знаете, как долго строка, которую вы пытаетесь соответствовать. К счастью, это не проблема, потому что вы смотрите только на конец строки $.

+0

Это не сработает для моих примеров, в первом примере он будет соответствовать «bar :: 0». – jpabluz

+0

Это не сработает - '+' является жадным, и так, например, будет соответствовать 'bar :: 0-3aab' в' foo :: bar :: 0-3aab'. –

+0

Извините, это все равно не сработает, но не потому, что я сказал. –

0
var string2 = string.replace(/.*::/, ""); 

хотя, возможно, string не лучший выбор имени для вашей строки?

+0

ха-ха да, имя было просто для иллюстрации целей. знак равно – jpabluz

1

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

function lastToken(str) { 
    var xs = str.split('::'); 
    return xs.length > 1 ? xs.pop() : null; 
} 

Если вы действительно хотите просто регулярное выражение, вы можете использовать /::((?:[^:]|:(?!:))*)$/. Во-первых, он соответствует литералу ::. Затем мы используем круглые скобки, чтобы поместить желаемую вещь в группу 1 захвата. Желательной является одна или несколько копий строки (?:...); эти группы брекетинга без захвата. Затем мы ищем либо [^:], либо несимметричный символ, либо :(?!:), двоеточие, за которым следует не-двоеточие. (?!...) - это негативный взгляд, который соответствует только если следующий токен не соответствует содержащемуся шаблону. Так как JavaScript не поддерживает отрицательный просмотр назад, я не могу видеть хороший способ, чтобы избежать захвата ::, как хорошо, но вы можете обернуть это в функции:

function lastTokenRegex(str) { 
    var m = str.match(/::((?:[^:]|:(?!:))*)$/); 
    return m && m[1]; 
} 
Смежные вопросы