Быстрый, грязный и почти не псевдокодовый ответ:
StringBuilder sb = new StringBuilder("[");
Set<Character> metaChars = //...appropriate initialization
while (sourceString.length() != 0) {
char c = sourceString.charAt(0);
sb.append(metaChars.contains(c) ? "\\"+c : c);
sourceString.replace(c,'');
}
sb.append("]");
Pattern p = Pattern.compile(sb.toString());
//...can check here for the appropriate sb.length cases
// e.g, 2 = empty, all chars equals the count of whatever set qualifies as all chars, etc
, который дает вам уникальную строку символов, с которой вы хотите сопоставить, с метасимволами заменены.Это не будет преобразовывать вещи в диапазоны (что я думаю хорошо - для меня это пахнет преждевременной оптимизацией).Вы можете выполнить некоторые пост-тесты для простых установленных случаев - например, сопоставление sb
с цифрами, нецифрами и т. Д., Но если вы не знаете, что это принесет вам большую производительность (или упрощениесмысл этой программы), я бы не стал беспокоиться.
Если вы действительно хотите сделать диапазоны, вы можете вместо этого sourceString.toCharArray()
отсортировать, повторить удаление повторений и выполнить какую-то проверку диапазона и заменить метасимволы.когда вы добавляете содержимое в StringBuilder
.
РЕДАКТИРОВАТЬ: Мне на самом деле понравилась версия toCharArray
, так что псевдокодирован также:
//...check for empty here, if not...
char[] sourceC = sourceString.toCharArray();
Arrays.sort(sourceC);
lastC = sourceC[0];
StringBuilder sb = new StringBuilder("[");
StringBuilder range = new StringBuilder();
for (int i=1; i<sourceC.length; i++) {
if (lastC == sourceC[i]) continue;
if (//.. next char in sequence..//) //..add to range
else {
// check range size, append accordingly to sb as a single item, range, etc
}
lastC = sourceC[i];
}