Проверка наличия одной-двух звездочек в начале слова

#regex

#регулярное выражение

Вопрос:

Необходимо проверить, имеет ли слово одну или максимум две звездочки в начале слова, начиная с трех, оно должно их игнорировать.

слова:

 [
 '* 11 13 24.574 1,474.79'
 '** 11 13 24.574 1,474.79'
 '*** 11 13 24.574 1,474.79'
]
  

Тест:

 1. ^[**]
2. ^[*][*]
3. (^*{1}s)
4. ^*|*s
  

Ожидается:

 [
 '* 11 13 24.574 1,474.79',
 '** 11 13 24.574 1,474.79'
]
  

Комментарии:

1. Вместо «слова» вы имеете в виду «строку»? И вы ищете регулярное выражение, которое будет соответствовать только строкам, начинающимся с одной или двух звездочек, за которыми следует пробел? Являются ли выражения под ‘Test:’ теми, которые вы пробовали до сих пор? Почему бы просто не ^**?s ?

2. Тест @Grismar: это регулярное выражение, которое я пробовал, и ничего regexr.com/5b0r9 ^**?s не является ожидаемым результатом

Ответ №1:

Когда вы произносите слова, я предполагаю, что у вас есть все «слова», перечисленные в векторе. Это должно выглядеть так:

  string_vector <- c("* 11 13 24.574 1,474.79", "** 11 13 24.574 1,474.79", "*** 11 13 24.574 1,474.79")
  

Проблема с тестом 1 заключается в том, что [] выбирает любой из элементов внутри скобок, поэтому ^ [**] просто ищет одну звездочку в начале строки. Все 3 слова будут сопоставлены. Второй тест будет соответствовать любому случаю, когда в начале есть 2 звездочки, которые включают все 3 строки в вашем векторе. Тест 3 соответствует ровно одной звездочке в начале, за которой следует пробел, который вернет только первый элемент. Тест 4 соответствует либо одной звездочке в начале, либо звездочке, за которой следует пробел в любом месте строки, что приведет к совпадениям во всех элементах вектора. Вам нужно было бы использовать ^ после | , чтобы иметь выбор между двумя разными шаблонами в качестве первого символа. Однако неясно, почему это применимо к вашему вопросу, поскольку 2 звездочки в начале не будут совпадать. Вы можете проверить все это самостоятельно, используя функцию «str_view_all» в пакете stringr. Вам нужно будет использовать две обратные косые черты перед * и s , если они не заключены в квадратные скобки.

Я предлагаю использовать следующее:

     library(stringr)
    str_subset(string_vector,"^\*{1,2}[^*]. ")
  

Это соответствует всем элементам вашего вектора, которые имеют ровно 1 или 2 звездочки в начале "^\*{1,2}" и не имеют больше звездочек, связанных с исходной одной или двумя [^*] . Тогда ". " означает, что любые другие символы могут занимать остальную часть строки.

Эта команда выдает желаемый результат

     [1] "* 11 13 24.574 1,474.79"  "** 11 13 24.574 1,474.79"
  

вы можете назначить объекту, если хотите сделать больше с результирующим вектором

     object <- str_subset(string_vector,"^\*{1,2}[^*]. ")
  

РЕДАКТИРОВАТЬ на основе полезных комментариев Кэри Свовленда:

Если также предполагается, что совпадают только "**" и "*" , то должно работать следующее выражение. Основываясь на предоставленных данных, я предположил, что после * ‘s в начале всегда будет больше символов, но теперь я вижу, что в описании не было явного утверждения, которое логически привело бы к этому предположению.

     object <- str_subset(string_vector,"^*(?!\*)|^\*{2}(?!\*)")
  

Это будет соответствовать:

  1. за одним * не следует другое * ИЛИ
  2. за двумя * не следует еще одна *

(?!) Представляет собой отрицательный прогноз. т. Е. символ (ы), подлежащий сопоставлению (в данном случае 1 или 2 * ), не может непосредственно предшествовать символу в круглых скобках после (?!) (в данном случае другой, * который экранируется с помощью \ ). Кэри также прав, указывая, что, поскольку нас интересует только начало строки, не имеет значения, есть ли еще какие-либо символы после 1 или 2 * , представляющие интерес.

Комментарии:

1. Неясно, должны ли совпадать строки "*" и "**" , но если это так, ваше регулярное выражение завершится ошибкой.

Ответ №2:

Это может сработать для вас:

https://regex101.com/r/OyGxta/2

Тестовая строка:

 * 11 13 24.574 1,474.79
** 11 13 24.574 1,474.79
*** 11 13 24.574 1,474.79
  

Шаблон:

 ^*{1,2}(?!*).*
  

Комментарии:

1. Вы правы в конце.* в отличие от . как я сделал

2. .* В конце имеет какой-либо эффект? Имейте в виду, что регулярное выражение необходимо только для проверки.

3. Это правильный момент — я просто сделал это, потому что подумал, что им может понадобиться строка текста. Я полагаю, что это можно было бы еще больше уменьшить.