Как соответствовать последнему вхождению паттерна? - PullRequest
0 голосов
/ 11 января 2019

Учитывая, что у меня есть следующая строка:

String 1 | string 2 | string 3

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

Прямо сейчас я использую это: /[^|]+$/i, но он также возвращает символ пробела после канала.

https://regex101.com/r/stnW0D/1

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Без регулярного выражения:

"String 1 | string 2 | string 3".split(" | ").last # => "string 3"
0 голосов
/ 12 января 2019
str = "string 1 | string 2 | string 3"

r = /
    .*  # match any number of any character (greedily)
    \|  # match a pipe
    [ ] # match a space
    \K  # forget everything matched so far  
    .+  # match remainder of string
    /x  # free-spacing regex definition mode

str[r]
  #=> "string 3"

Регулярное выражение обычно записывается следующим образом:

r = /.*\| \K.+/

При записи в свободном интервале пробел, следующий за каналом, должен быть заключен в класс символов, иначе Ruby преобразует его в пустую строку.

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

Вот несколько других способов:

str[2 + str.rindex('| ')..-1]
  #=> "string 3" 

str.reverse[/.*?(?= \|)/].reverse
  #=> "string 3" 
0 голосов
/ 12 января 2019
'String 1 | string 2 | string 3'[/(?<=\|\s)(\w+\s\d+\z)/]
# "string 3"

Где (сбежал):

\|  # a pipe
\s  # a whitespace
\w+ # one or more of any word character
\s  # a whitespace
\d+ # one or more digits
\z  # end of string

(...)    # capture everything enclosed
(?<=...) # a positive lookbehind

Обратите внимание, что в этом случае регулярное выражение уже получает последнее вхождение шаблона в строку, прикрепляя его к концу строки (\ z). В другом случае вы можете использовать [\|\s]? вместо (\ | \ s) для сопоставления строки, за которой следует пробел и число, и оттуда получить доступ к последнему элементу в возвращаемом массиве:

'String 1 | string 2 | string 3'.scan(/[\|\s]?(\w+\s\d+)/).last
# ["string 3"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...