Вопрос о регулярном выражении - один или несколько пробелов за пределами блока текста, заключенного в кавычки
Вопрос
Я хочу заменить любое вхождение более чем одного пробела одним пробелом, но не предпринимать никаких действий в тексте между кавычками.
Есть ли какой-нибудь способ сделать это с помощью регулярного выражения Java?Если да, не могли бы вы, пожалуйста, попробовать это или дать мне подсказку?
Решение
Вот еще один подход, который использует предварительный просмотр для определения того, что все кавычки после текущей позиции идут в виде совпадающих пар.
text = text.replaceAll(" ++(?=(?:[^\"]*+\"[^\"]*+\")*+[^\"]*+$)", " ");
При необходимости, средство просмотра может быть адаптировано для обработки экранированных кавычек внутри цитируемых разделов.
Другие советы
При попытке сопоставить что-то, что может содержаться внутри чего-то другого, может быть полезно создать регулярное выражение, которое соответствует обоим, например:
("[^"\\]*(?:\\.[^"\\]*)*")|( +)
Это будет соответствовать строке, заключенной в кавычки, или двум или более пробелам.Поскольку два выражения объединены, оно будет соответствовать строке, заключенной в кавычки, или двум или более пробелам, но не пробелам внутри кавычек.Используя это выражение, вам нужно будет проверить каждое совпадение, чтобы определить, является ли оно строкой в кавычках или двумя или более пробелами, и действовать соответствующим образом:
Pattern spaceOrStringRegex = Pattern.compile( "(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|( +)" );
StringBuffer replacementBuffer = new StringBuffer();
Matcher spaceOrStringMatcher = spaceOrStringRegex.matcher( text );
while ( spaceOrStringMatcher.find() )
{
// if the space group is the match
if ( spaceOrStringMatcher.group( 2 ) != null )
{
// replace with a single space
spaceOrStringMatcher.appendReplacement( replacementBuffer, " " );
}
}
spaceOrStringMatcher.appendTail( replacementBuffer );
текст между кавычками: находятся ли кавычки в одной или нескольких строках?
Обозначьте его и выделите один пробел между токенами.Появился быстрый поиск в Google "java tokenizer, который обрабатывает кавычки":эта ссылка
YMMV
Редактировать:ТАК что мне не понравилась эта ссылка.Вот ссылка для поиска в Google: Google.Это был первый результат.
Лично я не использую Java, но этот RegExp может помочь:
([^\" ])*(\\\".*?\\\")*
Попытка выражения с RegExBuddy, он генерирует этот код, выглядит хорошо для меня:
try {
Pattern regex = Pattern.compile("([^\" ])*(\\\".*?\\\")*", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
for (int i = 1; i <= regexMatcher.groupCount(); i++) {
// matched text: regexMatcher.group(i)
// match start: regexMatcher.start(i)
// match end: regexMatcher.end(i)
// I suppose here you must use something like
// sstr += regexMatcher.group(i) + " "
}
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
По крайней мере, в Python все работает нормально:
import re
text = """
este es un texto de prueba "para ver como se comporta " la funcion sobre esto
"para ver como se comporta " la funcion sobre esto "o sobre otro" lo q sea
"""
ret = ""
print text
reobj = re.compile(r'([^\" ])*(\".*?\")*', re.IGNORECASE)
for match in reobj.finditer(text):
if match.group() <> "":
ret = ret + match.group() + "|"
print ret
После того, как вы проанализируете цитируемый контент, запустите его для остальных, массовых или кусочных по мере необходимости:
String text = "ABC DEF GHI JKL";
text = text.replaceAll("( )+", " ");
// text: "ABC DEF GHI JKL"
Джефф, ты на правильном пути, но в твоем коде есть несколько ошибок, чтобы: 1) ты забыл экранировать кавычки внутри отрицательных классов символов; (2) Парены внутри первой группы захвата должны были быть не захватывающего сорта; (3) Если второй набор захватывающих паренов не участвует в матче, group (2)
возвращает ноль, и вы не проверяете это; и (4) если вы проверяете наличие двух или более пробелов в регулярном выражении вместо одного или нескольких , вам не нужно проверять длину соответствия позже. Вот пересмотренный код:
import java.util.regex.*;
public class Test
{
public static void main(String[] args) throws Exception
{
String text = "blah blah \"boo boo boo\" blah blah";
Pattern p = Pattern.compile( "(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|( +)" );
StringBuffer sb = new StringBuffer();
Matcher m = p.matcher( text );
while ( m.find() )
{
if ( m.group( 2 ) != null )
{
m.appendReplacement( sb, " " );
}
}
m.appendTail( sb );
System.out.println( sb.toString() );
}
}