Java regex - выражение с ровно одним пробелом - PullRequest
3 голосов
/ 29 января 2011

Я хочу сопоставить все выражения с одним пробелом.В настоящее время я использую [^\\s]*\\s[^\\s]*.Хотя это не очень хороший способ.

Ответы [ 6 ]

5 голосов
/ 29 января 2011

Почему бы и нет? Это нормально, просто немного усложнено:

\\S*\\s\\S*
1 голос
/ 29 января 2011

Я хочу сопоставить все выражения с одним пробелом.

Правильный шаблон для определения наличия пробелов в строке Java:

\A[^\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*+[\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000][\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*+\z

Другие ответы, представленные здесь, не дают правильного ответа на заданный вопрос.

Здесь приведены все пробельные символы Юникода, а также их возраст (то есть, в каком выпуске Юникода они впервые появились) и связанные с ними двоичные свойствана расстояние вопросы.

U+0009 CHARACTER TABULATION
    \s \h \pC \p{Cc}
    Age=1.1 HorizSpace Pattern_White_Space Space White_Space
U+000A LINE FEED (LF)
    \s \v \R \pC \p{Cc}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+000B LINE TABULATION 
    \v \R \pC \p{Cc}
    Pattern_White_Space Space VertSpace White_Space 
U+000C FORM FEED (FF)
    \s \v \R \pC \p{Cc}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+000D CARRIAGE RETURN (CR)
    \s \v \R \pC \p{Cc}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+0020 SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Pattern_White_Space Space Space_Separator White_Space
U+0085 NEXT LINE (NEL)
    \s \v \R \pC \p{Cc}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+00A0 NO-BREAK SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+1680 OGHAM SPACE MARK
    \s \h \pZ \p{Zs}
    Age=3.0 HorizSpace Space Space_Separator White_Space
U+180E MONGOLIAN VOWEL SEPARATOR
    \s \h \pZ \p{Zs}
    Age=3.0 HorizSpace Space Space_Separator White_Space
U+2000 EN QUAD
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2001 EM QUAD
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2002 EN SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2003 EM SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2004 THREE-PER-EM SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2005 FOUR-PER-EM SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2006 SIX-PER-EM SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2007 FIGURE SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2008 PUNCTUATION SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2009 THIN SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+200A HAIR SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space
U+2028 LINE SEPARATOR
    \s \v \R \pZ \p{Zl}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+2029 PARAGRAPH SEPARATOR
    \s \v \R \pZ \p{Zp}
    Age=1.1 Pattern_White_Space Space VertSpace White_Space
U+202F NARROW NO-BREAK SPACE
    \s \h \pZ \p{Zs}
    Age=3.0 HorizSpace Space Space_Separator White_Space
U+205F MEDIUM MATHEMATICAL SPACE
    \s \h \pZ \p{Zs}
    Age=3.2 HorizSpace Space Space_Separator White_Space
U+3000 IDEOGRAPHIC SPACE
    \s \h \pZ \p{Zs}
    Age=1.1 HorizSpace Space Space_Separator White_Space

Обратите внимание, что все, кроме четырех, присутствовали с тех пор еще в далеком юникоде 1.1.U + 1680 OGHAM SPACE MARK, U + 180E монгольский разделитель гласных и U + 202F NARROW NO-BREAK SPACE вошли в стандарт Unicode с выпуском 3.0, а U + 205F СРЕДНЕГО МАТЕМАТИЧЕСКОГО ПРОСТРАНСТВА впервые появилось с выпуском 3.2.Больше не было добавлено с тех пор.

Свойство \p{Whitespace} требуется для соответствия UTS # 18 RL1.2 «Свойства» , а также псевдоним \p{space} и\s ярлык для пробела необходим для соответствия UTS # 18 RL1.2a «Свойства совместимости» .

Как объяснено в Документ соответствия стандарту Unicode 6.0.0 , свойство White_Space является нормативным свойством, а не информативным, обязательным или предварительным свойством.Поскольку это нормативное свойство, вы строго обязаны использовать эти значения для правильной обработки всех символьных данных Unicode в соответствии со стандартом Unicode.

Ничто в jurPattern не обеспечивает функциональность, совместимую со стандартом Unicodeв этой связи.Фактически, регулярные выражения Java не удовлетворяют половине обязательных требований , необходимых даже для самого низкого возможного уровня соответствия, установленного в UTS # 18: Регулярные выражения Unicode .Этот минимальный уровень - Уровень 1, о котором написано:

Уровень 1 - минимально полезный уровень поддержки Юникода.Все реализации регулярных выражений, имеющие дело с Unicode, должны быть как минимум на уровне 1.

Поскольку регулярные выражения Java не удовлетворяют даже этим самым минимальным требованиям, необходимым для работы с Unicode, Регулярные выражения Java не минимальныполезно для работы с Юникодом. Поэтому вы должны прибегнуть к таким явным перечислениям, как указано выше, если вы хотите создать согласованное поведение.Возможно, вы захотите использовать мою библиотеку для перезаписи шаблонов .

0 голосов
/ 29 января 2011
String[] ss = { " ", "abc", "a bc", "a b c d" };
Matcher m = Pattern.compile("^\\S*\\s\\S*$").matcher("");
for (String s : ss)
{
  if (m.reset(s).matches())
  {
    System.out.printf("%n>>%s<< OK%n", s);
  }
}

вывод:

>> << OK

>>a bc<< OK
0 голосов
/ 29 января 2011

Используйте транслитерацию. Это должен быть независимый тест, приведенное выше регулярное выражение не может быть объединено с большим регулярным выражением и все еще проверять один пробел.

Транслитерация в этом тесте в 10-20 раз быстрее, чем регулярное выражение.
Это пример JTR:

String aInput = "This is a test, 123.";
CharacterReplacer cReplacer = Perl5Parser.makeReplacer( "tr[ \\t\\r\\n\\f\\x0B][ \\t\\r\\n\\f\\x0B]" );
String aResult = cReplacer.doReplacement( aInput );
int nMatches = cReplacer.getMatches();

if (nMatches == 1) { ... }
0 голосов
/ 29 января 2011

Вы также можете проверить это с помощью indexOf:

String s = "some text";
int indexOf = s.indexOf(' ');
boolean isOneWhitespace = (indexOf >= 0 && indexOf == s.lastIndexOf(' '));
0 голосов
/ 29 января 2011

Другой способ сделать это, если вы не хотите идти по пути регулярных выражений (возможное увеличение производительности):

String s = "one whitespace";


public boolean hasOneWhitespace(String s) {
   int count = 0;
   for (int i = 0; i < s.length(); i++) {
      if(s.charAt(i) == ' ') {
         count++;
         if (count > 1) return false;
      }
   }
   return count == 1;   
}

Конечно, это будет работать, только если вы считаете " " пробелом. Вкладки и переводы строк не будут работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...