@AranMulholland: Любой, у кого есть характерно-ориентированный принтер. Большинство принтеров имеют символьный режим, а также PostScript или любой другой интерфейс, который называется Hewlett Packard, и для отправки страницы вы отправляете ленту новостей.
Бородин,
1
@Borodin Hewlett Packard's называется PCL (язык управления принтером).
CB_Ron
Ответы:
182
Perl версии 5.10 и более поздних версий поддерживает вспомогательные классы по вертикали и горизонтали характер, \vи \h, а также общий пробельные класс символов\s
Самое чистое решение - использовать класс символов горизонтальных пробелов\h . Это будет соответствовать символу табуляции и пробелу из набора ASCII, неразрывному пробелу из расширенного ASCII или любому из этих символов Unicode
U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE (not matched by \s)
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE
Вертикальное пространство шаблон \vменее полезен, но эти символы соответствуют
U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0085 NEXT LINE (not matched by \s)
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
Есть семь вертикальных пробельных символов, которые соответствуют, \vи восемнадцать горизонтальных, которые соответствуют \h. \sсоответствует двадцать три символа
Все пробельные символы являются вертикальными или горизонтальными без перекрытия, но они не являются правильными подмножествами, поскольку \hтакже соответствуют U + 00A0 NO-BREAK SPACE, а \vтакже соответствуют U + 0085 NEXT LINE, ни один из которых не соответствует\s
\hработает только на тех языках, которые поддерживает PCRE.
Авинаш Радж
14
@AvinashRaj: Этот вопрос касается Perl, который, безусловно, поддерживает PCRE
Бородин
2
@AvinashRaj: За исключением того, что [[:blank:]]это не соответствует пространству без перерывов - или"\xA0"
Бородин
6
Хочу упомянуть, что это \hпрекрасно работает для моего варианта использования, который выполнял поиск / замену в Notepad ++ на 1 или более смежных пробелах, не начинающихся с новой строки. Ничто другое (простое) не сработало.
Squidbe
8
Что делает Perl \hслегка нестандартным, так это его включение MONGOLIAN VOWEL SEPARATOR. Юникод не считает это пробелом. По этой причине Perl \hотличается от POSIX blank( [[:blank:]]в Perl, \p{Blank}в Java) и Java 8 \h. Правда, это крайний случай.
Александр Дубинский
363
Используйте двойной негатив:
/[^\S\r\n]/
То есть не-не-пробел (заглавная S дополняет) или не-возврат каретки или не-перевод строки. Распределение внешнего не ( т.е. дополнения ^в классе символов) по закону Де Моргана , это эквивалентно «пробелу, но не возврату каретки или переводу строки». Включение обоих \rи \nв шаблон корректно обрабатывает все соглашения Unix (LF), классической Mac OS (CR) и DOS-ish (CR LF) .
До Perl v5.18 \sне соответствовал вертикальной табуляции. [^\S\cK](неясно) соответствует тому, что \sтрадиционно делали.
В том же разделе perlrecharclass также предлагаются другие подходы, которые не оскорбят противодействия учителей языка двойным негативам.
Вне локали и правил Unicode или когда действует /aпереключатель, « \sсоответствует [\t\n\f\r ]и, начиная с Perl v5.18, вертикальная вкладка \cK». Откажитесь \rи \nоставьте /[\t\f\cK ]/для соответствующего пробела, но не перевод строки.
Если ваш текст - Unicode, используйте код, подобный приведенному ниже, для создания шаблона из таблицы в вышеупомянутом разделе документации .
sub ws_not_nl {local($_)=<<'EOTable';0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]0x00a0 NO-BREAK SPACE h s [2]0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTablemy $class;while(/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg){my($hex,$name)=($1,$2);nextif $name =~/\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .="\\N{U+$hex}";}
qr/[$class]/u;}
Другие приложения
Двойной отрицательный трюк также удобен для сопоставления буквенных символов. Помните , что \wматчи «символы, слова» буквенные символы и цифры и подчеркивания. Мы, некрасивые американцы, иногда хотим написать это, скажем,
if(/[A-Za-z]+/){...}
но дважды отрицательный символьный класс может уважать локаль:
if(/[^\W\d_]+/){...}
Выражение «символ слова, но не цифра или подчеркивание» таким образом немного непрозрачно. Символьный класс POSIX сообщает намерение более напрямую
Умно, но поведение очень удивительно, и я не вижу, как это менее неловко.
Qwertie
7
@Qwertie: что удивительного? Менее неловко, чем что?
ysth
9
Отлично ужасно.
9
Это очень хорошо. В соответствии с запросом вы сопоставляете пробелы (не только некоторые пробельные символы) и исключаете символ перевода строки. Ваше решение не касается вопроса: «какие пробельные символы существуют», как это не должно быть. Это именно то, что я искал. (Как было отмечено @Rory, а «перевод строки» может также включать в себя \r, например , на Windows, так считают exluding те от матча , а также: /[^\S\r\n]/)
Timo
1
Это, безусловно, удовлетворит потребности ОП и практически всех, кто занимается поиском этого вопроса (во всяком случае, на английском языке). Но это все еще плохой ответ. Там просто нет оправдания для использования этого решения, когда \hдоступно.
Алан Мур
50
Вариант ответа Грега, который также включает возврат каретки:
/[^\S\r\n]/
Это регулярное выражение безопаснее, чем /[^\S\n]/без \r. Я рассуждаю так: Windows использует \r\nновые строки, а Mac OS 9 использует \r. Вы вряд ли найдете \rбез нас в \nнаше время, но если вы найдете это, это не может означать ничего, кроме новой строки. Таким образом, поскольку \rможет означать новую строку, мы должны исключить ее тоже.
+1 Решение Грега испортило мой текст, твое сработало нормально.
Тимо Хуовинен
Вы можете быть удивлены тем, сколько программ по-прежнему используют «\ r» для окончания строк. Иногда мне требовалось время, чтобы понять, что моя проблема в том, что файл использовал их. Или что он использовал кодировку символов MacRoman ...
mivk
2
Похоже, @Greg сначала «неправильно» изменил его и не кредитовал вас. Вот почему я здесь голосую.
Андре Элрико
14
Приведенное ниже регулярное выражение будет соответствовать пробелам, но не символу новой строки.
Я не знаю, почему вы, люди, не упомянули класс символов POSIX, [[:blank:]]который соответствует любым горизонтальным пробелам ( пробелы и табуляции ). Этот класс POSIX chracter будет работать с BRE ( базовые регулярные выражения ), ERE ( расширенное регулярное выражение ), PCRE ( регулярное выражение, совместимое с Perl ).
То, что вы ищете, это blankкласс символов POSIX . В Perl это упоминается как:
[[:blank:]]
в Java (не забудьте включить UNICODE_CHARACTER_CLASS):
\p{Blank}
По сравнению с аналогом \h, POSIX blankподдерживается еще несколькими движками регулярных выражений ( ссылка ). Основным преимуществом является то, что его определение зафиксировано в Приложении C: Свойства совместимости регулярных выражений Unicode и стандарт для всех разновидностей регулярных выражений, поддерживающих Unicode. (Например, \hв Perl выбирается дополнительное включение MONGOLIAN VOWEL SEPARATOR.) Однако аргумент в пользу этого \hзаключается в том, что он всегда обнаруживает символы Unicode (даже если движки не согласны с какими), в то время как классы символов POSIX часто по умолчанию ASCII. только (как в Java).
Но проблема в том, что даже придерживание Unicode не решает проблему на 100%. Рассмотрим следующие символы, которые не считаются пробелами в Юникоде:
U + 180E монгольский разделитель гласных
U + 200B НУЛЕВОЕ ПРОСТРАНСТВО
U + 200C с нулевой шириной без соединения
U + 200D ZERO ШИРОКИЙ СОЕДИНИТЕЛЬ
U + 2060 WORD JOINER
U + FEFF с нулевой шириной неразрывного пространства
Вышеупомянутый монгольский разделитель гласных не включен, что, вероятно, является веской причиной. Это, наряду с 200C и 200D, происходит в словах (AFAIK), и поэтому нарушает кардинальное правило, которому подчиняются все остальные пробелы: вы можете токенизировать его. Они больше похожи на модификаторы. Однако ZERO WIDTH SPACE, WORD JOINERи ZERO WIDTH NON-BREAKING SPACE(если он используется в качестве кроме отметки порядка байтов) подходит правило пробела в моей книге. Поэтому я включаю их в свой класс горизонтальных пробельных символов.
В Java:
static public final String HORIZONTAL_WHITESPACE ="[\\p{Blank}\\u200B\\u2060\\uFFEF]"
Вам необходимо добавить соответствующие флаги компиляции regexp в компиляцию Java и использовать Java 7 или более позднюю версию. В любом случае, вопрос был не о Java или PCRE вообще, так что все это несущественно.
трилист
@tchrist Спасибо, что указали на это. Я обновлю свой ответ. Я не согласен, однако, что мой ответ не имеет значения. Что является несущественным, так это perlтег в оригинальном вопросе.
Александр Дубинский
1
@AleksandrDubinsky, \ p {Blank} не поддерживается в JavaScript, поэтому определенно не «стандарт для всех разновидностей регулярных выражений» -1
Валентин Васильев
Наиболее информативно. Я нахожу тревожным знать, что общий и полный класс символов «горизонтальный пробел» не существует, и что [\p{Blank}\u200b\u180e]требуются ужасы вроде . Правда, имеет смысл, что разделитель гласных не считается пробельным символом, но почему пробел нулевой ширины не в таких классах, как \sи \p{Blank}, лучше меня.
Тимо
Продолжение: я прочитал, что оба считаются «нейтральными по отношению к границе», хотя это не объясняет почему .
Тимо
-4
m/ /gпросто дайте место / /, и это будет работать. Или используйте \S- он заменит все специальные символы, такие как табуляция, новые строки, пробелы и так далее.
[\r\f]
.Ответы:
Perl версии 5.10 и более поздних версий поддерживает вспомогательные классы по вертикали и горизонтали характер,
\v
и\h
, а также общий пробельные класс символов\s
Самое чистое решение - использовать класс символов горизонтальных пробелов
\h
. Это будет соответствовать символу табуляции и пробелу из набора ASCII, неразрывному пробелу из расширенного ASCII или любому из этих символов UnicodeВертикальное пространство шаблон
\v
менее полезен, но эти символы соответствуютЕсть семь вертикальных пробельных символов, которые соответствуют,
\v
и восемнадцать горизонтальных, которые соответствуют\h
.\s
соответствует двадцать три символаВсе пробельные символы являются вертикальными или горизонтальными без перекрытия, но они не являются правильными подмножествами, поскольку
\h
также соответствуют U + 00A0 NO-BREAK SPACE, а\v
также соответствуют U + 0085 NEXT LINE, ни один из которых не соответствует\s
источник
\h
работает только на тех языках, которые поддерживаетPCRE
.[[:blank:]]
это не соответствует пространству без перерывов -
или"\xA0"
\h
прекрасно работает для моего варианта использования, который выполнял поиск / замену в Notepad ++ на 1 или более смежных пробелах, не начинающихся с новой строки. Ничто другое (простое) не сработало.\h
слегка нестандартным, так это его включениеMONGOLIAN VOWEL SEPARATOR
. Юникод не считает это пробелом. По этой причине Perl\h
отличается от POSIXblank
([[:blank:]]
в Perl,\p{Blank}
в Java) и Java 8\h
. Правда, это крайний случай.Используйте двойной негатив:
То есть не-не-пробел (заглавная S дополняет) или не-возврат каретки или не-перевод строки. Распределение внешнего не ( т.е. дополнения
^
в классе символов) по закону Де Моргана , это эквивалентно «пробелу, но не возврату каретки или переводу строки». Включение обоих\r
и\n
в шаблон корректно обрабатывает все соглашения Unix (LF), классической Mac OS (CR) и DOS-ish (CR LF) .Не нужно верить мне на слово:
Вывод:
Обратите внимание на исключение вертикальной вкладки, но это рассматривается в v5.18 .
Прежде чем возражать слишком жестко, в документации Perl используется та же техника. Сноска в разделе «Пробелы» в perlrecharclass гласит:
В том же разделе perlrecharclass также предлагаются другие подходы, которые не оскорбят противодействия учителей языка двойным негативам.
Вне локали и правил Unicode или когда действует
/a
переключатель, «\s
соответствует[\t\n\f\r ]
и, начиная с Perl v5.18, вертикальная вкладка\cK
». Откажитесь\r
и\n
оставьте/[\t\f\cK ]/
для соответствующего пробела, но не перевод строки.Если ваш текст - Unicode, используйте код, подобный приведенному ниже, для создания шаблона из таблицы в вышеупомянутом разделе документации .
Другие приложения
Двойной отрицательный трюк также удобен для сопоставления буквенных символов. Помните , что
\w
матчи «символы, слова» буквенные символы и цифры и подчеркивания. Мы, некрасивые американцы, иногда хотим написать это, скажем,но дважды отрицательный символьный класс может уважать локаль:
Выражение «символ слова, но не цифра или подчеркивание» таким образом немного непрозрачно. Символьный класс POSIX сообщает намерение более напрямую
или со свойством Unicode как предложено szbalint
источник
\r
, например , на Windows, так считают exluding те от матча , а также:/[^\S\r\n]/
)\h
доступно.Вариант ответа Грега, который также включает возврат каретки:
Это регулярное выражение безопаснее, чем
/[^\S\n]/
без\r
. Я рассуждаю так: Windows использует\r\n
новые строки, а Mac OS 9 использует\r
. Вы вряд ли найдете\r
без нас в\n
наше время, но если вы найдете это, это не может означать ничего, кроме новой строки. Таким образом, поскольку\r
может означать новую строку, мы должны исключить ее тоже.источник
Приведенное ниже регулярное выражение будет соответствовать пробелам, но не символу новой строки.
DEMO
Если вы хотите добавить возврат каретки и затем добавить
\r
с|
оператором внутри отрицательного предпросмотра.DEMO
Добавьте
+
после группы без захвата, чтобы соответствовать один или несколько пробелов.DEMO
Я не знаю, почему вы, люди, не упомянули класс символов POSIX,
[[:blank:]]
который соответствует любым горизонтальным пробелам ( пробелы и табуляции ). Этот класс POSIX chracter будет работать с BRE ( базовые регулярные выражения ), ERE ( расширенное регулярное выражение ), PCRE ( регулярное выражение, совместимое с Perl ).DEMO
источник
То, что вы ищете, это
blank
класс символов POSIX . В Perl это упоминается как:в Java (не забудьте включить
UNICODE_CHARACTER_CLASS
):По сравнению с аналогом
\h
, POSIXblank
поддерживается еще несколькими движками регулярных выражений ( ссылка ). Основным преимуществом является то, что его определение зафиксировано в Приложении C: Свойства совместимости регулярных выражений Unicode и стандарт для всех разновидностей регулярных выражений, поддерживающих Unicode. (Например,\h
в Perl выбирается дополнительное включениеMONGOLIAN VOWEL SEPARATOR
.) Однако аргумент в пользу этого\h
заключается в том, что он всегда обнаруживает символы Unicode (даже если движки не согласны с какими), в то время как классы символов POSIX часто по умолчанию ASCII. только (как в Java).Но проблема в том, что даже придерживание Unicode не решает проблему на 100%. Рассмотрим следующие символы, которые не считаются пробелами в Юникоде:
U + 180E монгольский разделитель гласных
U + 200B НУЛЕВОЕ ПРОСТРАНСТВО
U + 200C с нулевой шириной без соединения
U + 200D ZERO ШИРОКИЙ СОЕДИНИТЕЛЬ
U + 2060 WORD JOINER
U + FEFF с нулевой шириной неразрывного пространства
Взято с https://en.wikipedia.org/wiki/White-space_character
Вышеупомянутый монгольский разделитель гласных не включен, что, вероятно, является веской причиной. Это, наряду с 200C и 200D, происходит в словах (AFAIK), и поэтому нарушает кардинальное правило, которому подчиняются все остальные пробелы: вы можете токенизировать его. Они больше похожи на модификаторы. Однако
ZERO WIDTH SPACE
,WORD JOINER
иZERO WIDTH NON-BREAKING SPACE
(если он используется в качестве кроме отметки порядка байтов) подходит правило пробела в моей книге. Поэтому я включаю их в свой класс горизонтальных пробельных символов.В Java:
источник
perl
тег в оригинальном вопросе.[\p{Blank}\u200b\u180e]
требуются ужасы вроде . Правда, имеет смысл, что разделитель гласных не считается пробельным символом, но почему пробел нулевой ширины не в таких классах, как\s
и\p{Blank}
, лучше меня.m/ /g
просто дайте место/ /
, и это будет работать. Или используйте\S
- он заменит все специальные символы, такие как табуляция, новые строки, пробелы и так далее.источник