2015-01-14 4 views
6

В предложении аналогично:Как совместить '+ abc', но не '++ abc' без lookbehind?

Lorem Ipsum + Dolor ++ сидеть Амет.

Я хочу совместить +dolor, но не ++sit. Я могу сделать это с lookbehind, но так как JavaScript не поддерживает его, я изо всех сил пытаюсь построить шаблон для него.

До сих пор я пытался сделать это с:

(?:\+(.+?))(?=[\s\.!\!]) - but it matches both words 
(?:\+{1}(.+?))(?=[\s\.!\!]) - the same here - both words are matched 

и к моему удивлению, картина, как:

(?=\s)(?:\+(.+?))(?=[\s\.!\!]) 

ничего не найдено. Я думал, что смогу обмануть его и использовать \s или позже также ^ перед значком +, но он не работает так.


EDIT - справочная информация:

Это не обязательно часть вопроса, но иногда это хорошо, чтобы знать, что все это хорошо так, чтобы прояснить некоторые вопросы/комментарии краткое объяснение:

  • любое слово в любом порядке можно по ознаменован либо в + или ++
  • каждое слово, и это маркировка будет заменена <span> позже
  • случаи как Lorem + Ipsum являются concidered недействительным, поскольку это было бы как разделив слово (ро + ом) или написание двух слов в одно слово (myroom) поэтому он должен быть исправлен в любом случае (шаблон может соответствовать этому, но это не ошибка), следует, однако, по крайней мере соответствовать нормальным случаев, как в приведенном выше примере
  • Я использую предпросмотр как (?=[\s\.!\!]), так что я могу соответствовать словам в любом языке не только \w персональные данные
+0

Вы хотите совместить '+ bar' в' foo + bar'? –

+0

Нет, это предложение, и таких случаев не будет. Перед '+' всегда будет либо пробел '\ s', либо'^'. – t3chb0t

+0

, то почему вы приняли ответ, который захватывает '+ bar' в' foo + bar'? –

ответ

3

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

(?:^|[^+])(\+[^\s+.!]+) 

Однако это разрушается, если потенциальные совпадения могут быть непосредственно смежными друг с другом.

Протестируйте его live on regex101.com.

Объяснение:

(?:   # Match (but don't capture) 
^   # the position at the start of the string 
|   # or 
[^+]  # any character except +. 
)   # End of group 
(   # Match (and capture in group 1) 
\+   # a + character 
[^\s+.!]+ # one or more characters except [+.!] or whitespace. 
)   # End of group 
+0

Трудно подобрать ответ, но я думаю, что это приведет меня в правильном направлении, и я пойду с шаблоном типа '(?:^| \ S) (\ + ([^ + \ s] +)) (? = [\ s \.! \!])), который является комбинацией обоих шаблонов. Совпадение дополнительного персонажа в начале делало трюк. Я добавил другую группу, потому что мне нужно ее заменить позже, чтобы решить эту конкретную проблему. – t3chb0t

0

Просто попробуйте следующее регулярное выражение:

(^|\s)\+\w+ 
+0

, но это также соответствует предыдущему пространству. –

+0

@AvinashRaj: Я думаю, это не имеет значения - текст можно получить с группой захвата в любом случае. – nhahtdh

+0

, но ваше регулярное выражение совпадает с '+ dolor' в этой строке' foo + dolor'. –

3
\+\+|(\+\S+) 

захватить содержание от захвата группы 1. регулярное выражение использует трюк описанный in this answer.

Demo on regex101

var re = /\+\+|(\+\S+)/g; 
var str = 'Lorem ipsum +dolor ++sit ame'; 
var m; 
var o = []; 

while ((m = re.exec(str)) != null) { 
    if (m.index === re.lastIndex) { 
     re.lastIndex++; 
    } 

    if (m[1] != null) { 
     o.push(m[1]); 
    } 

} 

Если у вас есть вход как +++donor, используйте:

\+\++|(\+\S+) 
+0

почему downvoted ????????/ – vks

+1

Кто бы это ни сделал, очевидно, не знает разницы между захватом и не с захватом совпадений ... @ t3chb0t Я думаю, вам лучше принять этот ответ, поскольку он не страдает от проблемы со смежными совпадениями, такие как '+ dolor + sit' (где моя только найдет' + dolor'). –

+0

@TimPietzcker, он должен заменить тех, кого захватили чем-то другим. Поэтому уран лучше заменить в этом потребует больше усилий. – vks

1

Я думаю, что это то, что вам нужно.

(?:^|\s)(\+[^+\s.!]*)(?=[\s.!]) 
Смежные вопросы