Несколько вещей о вашем регулярном выражении:
(?<=\b)
совпадает с \b
, поскольку граница слова уже является утверждением нулевой ширины \@
так же, как @
, так как @
не является специальным метасимволом регулярных выражений, и вам не нужно экранировать его [^\s]+
совпадает с \S+
, почти все классы сокращенных символов имеют свои отрицательныедубликаты в регулярном выражении.
Итак, ваше регулярное выражение, \b@\S+
, соответствует @i
в h@i
, поскольку существует граница слова между h
(буква, слово char) и @
(не словесный символ, а не буква, цифра или знак подчеркивания).Проверьте этот отладчик регулярных выражений .
\b
- это неоднозначный шаблон, значение которого зависит от контекста регулярных выражений .В вашем случае вы можете захотеть использовать \B
, границу, не состоящую из слов, то есть \B@\S+
, и она будет соответствовать @
, которым предшествует символ без слова или в начале строки.
x <- c("h@i", "hi @hello @me")
regmatches(x, gregexpr("\\B@\\S+", x))
## => [[1]]
## character(0)
##
## [[2]]
## [1] "@hello" "@me"
См. Демонстрационную версию regex .
Если вы хотите избавиться от этой \b
/ \B
неоднозначности,используйте однозначные границы слов, используя обходные пути с методами stringr или базовые регулярные функции R с аргументом perl=TRUE
:
regmatches(x, gregexpr("(?<!\\w)@\\S+", x, perl=TRUE))
regmatches(x, gregexpr("(?<!\\S)@\\S+", x, perl=TRUE))
где:
(?<!\w)
- однозначный стартграница слова - это отрицательный вид сзади, который гарантирует, что слева от текущего местоположения или начала строки находится символ без слова (?<!\S)
- граница начального слова с пробелом - это отрицательный вид сзади, который гарантирует наличие пробела слева от текущего местоположения или начала строки.
См. это демонстрационное выражение regex и еще одна демонстрация регулярных выражений здесь .
Обратите внимание, что сосоответствующие правые границы (?!\w)
и (?!\S)
.