ou предложил
/"[\p{L}\p{Nd}а-яА-ЯёЁ -_\.\+]+"/ui
, который я отправляю, эквивалентно:
/"[\pL\p{Nd}а-яА-ЯёЁ -_.+]+"/ui
Чтобы показать людям, которые не используют ASCII, если это не очевидно, используйте \x{⋯}
экранирует, что:
/"[\pL\p{Nd}\x{430}-\x{44F}\x{410}-\x{42F}\x{451}\x{401} -_.+]+"/ui
И с использованием именованных символов:
/"[\pL\p{Nd}\N{CYRILLIC SMALL LETTER A}-\N{CYRILLIC SMALL LETTER YA}\N{CYRILLIC CAPITAL LETTER A}-\N{CYRILLIC CAPITAL LETTER YA}\N{CYRILLIC SMALL LETTER IO}\N{CYRILLIC CAPITAL LETTER IO} -_.+]+"/ui
Кстати, эти символы создаются при запуске их через уникальную цитату скрипт , первый - uniquote -x
, второй - uniquote -v
.
И да, я знаю или, по крайней мере, считаю, что PHP пока не поддерживает именованные символы, но это облегчаетговорить о.Кроме того, это гарантирует, что они не путают двойников:
U+0410 ‹А› \N{CYRILLIC CAPITAL LETTER A}
U+0430 ‹а› \N{CYRILLIC SMALL LETTER A}
U+0401 ‹Ё› \N{CYRILLIC CAPITAL LETTER IO}
U+0451 ‹ё› \N{CYRILLIC SMALL LETTER IO}
для:
U+0041 ‹A› \N{LATIN CAPITAL LETTER A}
U+0061 ‹a› \N{LATIN SMALL LETTER A}
U+00CB ‹Ë› \N{LATIN CAPITAL LETTER E WITH DIAERESIS}
U+00EB ‹ë› \N{LATIN SMALL LETTER E WITH DIAERESIS}
И теперь я думаю об этом, это все буквы, поэтому я не могу не видетьпочему вы перечисляете список кириллицы.Это потому, что вам не нужны все кириллические буквы, а скорее именно этот конкретный набор из них?В противном случае я бы просто сделал:
/"[\pL\p{Nd} -_.+]+"/ui
В этот момент я задаюсь вопросом об этом /i
.Я не могу понять, какова его цель, поэтому просто напишите:
/"[\pL\p{Nd} -_.+]+"/u
Как уже упоминалось, замена максимального количественного показателя +
на соответствующую минимальную версию, +?
, будет работать:
/"[\pL\p{Nd} -_.+]+?"/u
Однако меня беспокоит этот диапазон [ -_]
, то есть \p{SPACE}-\p{LOW LINE}
.Я считаю, что это очень специфический диапазон.Это означает, что любой из этих
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
Во-первых, вы снова включили заглавные буквы ASCII.С другой стороны, вы пропустили некоторые символы и знаки пунктуации:
% unichars -g '\p{ASCII}' '[\pS\pP]' 'ord() < ord(" ") || ord() > ord("_")'
` U+0060 GC=Sk GRAVE ACCENT
{ U+007B GC=Ps LEFT CURLY BRACKET
| U+007C GC=Sm VERTICAL LINE
} U+007D GC=Pe RIGHT CURLY BRACKET
~ U+007E GC=Sm TILDE
(Это вывод из сценария unichars , если вам интересно.)
Что странно произвольно.Поэтому мне интересно, может быть, это не достаточно хорошо для вас:
/"[\pL\p{Nd}\s\pS\pP]+?"/u
Теперь, когда я думаю об этом, эти два могут вызвать другие проблемы:
U+0401 ‹Ё› \N{CYRILLIC CAPITAL LETTER IO}
U+0451 ‹ё› \N{CYRILLIC SMALL LETTER IO}
Это предполагаетнаходятся в форме NFC (образованной каноническим составом канонического разложения).Если бы была вероятность того, что вы имеете дело с данными, которые не были нормализованы в форме NFC, то вам пришлось бы учитывать
NFD("\N{CYRILLIC CAPITAL LETTER IO}") => "\N{CYRILLIC SMALL LETTER IE}\N{COMBINING DIAERESIS}"
NFD("\N{CYRILLIC SMALL LETTER IO}") => "\N{CYRILLIC CAPITAL LETTER IE}\N{COMBINING DIAERESIS}"
И теперь у вас есть не-буквы!
% uniprops "COMBINING DIAERESIS"
U+0308 ‹◌̈› \N{COMBINING DIAERESIS}
\w \pM \p{Mn}
All Any Assigned InCombiningDiacriticalMarks Case_Ignorable CI Combining_Diacritical_Marks Dia Diacritic M Mn Gr_Ext Grapheme_Extend Graph GrExt ID_Continue IDC Inherited Zinh Mark Nonspacing_Mark Print Qaai Word XID_Continue XIDC
Так что, возможно, вы на самом деле захотите:
/"[\pL\pM\p{Nd}\s\pS\pP]+?"/u
Если вы хотите ограничить вашу строку, содержащую только символы из латинского или кириллического алфавита (а не, скажем, скажем,(Греч. Или катакана), то вы добавили бы предвидение этого эффекта:
/"(?:(?=[\p{Latin}\p{Cyrillic}])[\pL\pM\p{Nd}\s\pS\pP])+?"/u
За исключением того, что вам также нужно Common
, чтобы получить цифры и различные обозначения и символы, и вам нужно Inherited
длякомбинируя отметки после ваших писем.Это подводит нас к следующему:
/"(?:(?=[\p{Latin}\p{Cyrillic}\p{Common}\p{Inherited}])[\pL\pM\p{Nd}\s\pS\pP])+?"/u
Теперь предлагается другой способ добиться минимального совпадения между двойными кавычками:
/"(?:(?!")(?=[\p{Latin}\p{Cyrillic}\p{Common}\p{Inherited}])[\pL\pM\p{Nd}\s\pS\pP])+"/u
Что усложняется, чтобы не работать /x
mode:
/
" # literal double quote
(?:
### This group specifies a single char with
### three separate constraints:
# Constraint 1: next char must NOT be a double quote
(?!")
# Constraint 2: next char must be from one of these four scripts
(?=[\p{Latin}\p{Cyrillic}\p{Common}\p{Inherited}])
# Constraint 3: match one of either Letter, Mark, Decimal Number,
# whitespace, Symbol, or Punctuation:
[\pL\pM\p{Nd}\s\pS\pP]
) # end constraint group
+ # repeat entire group 1 or more times
" # and finally match another double-quote
/ux
Если бы это был Perl, я написал бы это с помощью m{⋯}xu
m{
" # literal double quote
(?:
### This group specifies a single char with
### three separate constraints:
# Constraint 1: next char must NOT be a double quote
(?!")
# Constraint 2: next char must be from one of these four scripts
(?=[\p{Latin}\p{Cyrillic}\p{Common}\p{Inherited}])
# Constraint 3: match one of either Letter, Mark, Decimal Number,
# whitespace, Symbol, or Punctuation:
[\pL\pM\p{Nd}\s\pS\pP]
) # end constraint group
+ # repeat entire group 1 or more times
" # and finally match another double-quote
}ux
Но я не знаю, можно ли использовать такие парные, заключающие в скобки разделители, как этов PHP.
Надеюсь, это поможет!