#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:
Это может сработать для вас:
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. Это правильный момент — я просто сделал это, потому что подумал, что им может понадобиться строка текста. Я полагаю, что это можно было бы еще больше уменьшить.