2015-12-17 2 views
2

(Мои программирования вопрос может показаться несколько хитрым, но я не вижу никакого другого решения.)Multiline RegEx в Java

Текст написан в редакторе Eclipse. При активировании самодельного плагина табличного представления для Eclipse качество текста проверяется автоматически с помощью активированного сценария Python (не редактируемого мной), который получает текст редактора. Текст редактора удаляется из символов пробела (\ n, \ t), за исключением нормального пространства (''), потому что в противном случае предложения не могут быть проверены на проверку качества. Когда скрипт завершен, он возвращает неверные предложения в таблицу.

Можно щелкнуть по предложениям в таблице, и плагин будет искать (строка за строку) в активном редакторе для нажатого предложения. Это работает для однострочных предложений. Тем не менее, многострочные предложения не могут быть найдены в активном редакторе, потому что все \ n и \ t отсутствуют в скомпилированном предложении.

Чтобы преодолеть эту проблему, я сменил сценарий так, чтобы весь текст редактора был как одна строка. Я пробовал следующее:

String newSentence = tableSentence.replaceAll(" ", "\\s+") 
Pattern p = Pattern.compile(newSentence) 
Matcher contentMatcher = p.matcher(editorContent) // editorContent is a string 
if (contentMatcher.find()) { 
    // Get index offset of string and length of string 
} 

Изменив все пробелы на \ s +, я надеялся, что получится матч. Однако это не сработает, потому что это будет выглядеть так:

  • editorContent: \ nright \ n \ ttasks.
  • tableSentence: Правильные задачи.
  • NewSentence: Thes + права + задачи. // После действия «replaceAll»
  • Должно быть: Задачи \ s + right \ s +.

Итак, мой вопрос: как я могу настроить вход для компилятора? Я неопытен, когда дело доходит до Java, поэтому я не вижу, как это изменить .. И я, к сожалению, не могу изменить сценарий Python, чтобы также вернуть полные предложения ...

+0

вы должны '«\\\\ s +»', так как '' \ '' также экранирующий символ в строке замены. Вы можете использовать 'Matcher.quoteReplacement (" \\ s + ")', чтобы избежать двойного escape-кода при замене литерала, содержащего '' \ ''. – nhahtdh

+0

На самом деле, в этом случае просто используйте функцию 'replace', так как он ожидает строку, а не регулярное выражение. – nhahtdh

ответ

2

Добавить третий и четвертый обратный сбой на ваш regex, поэтому он выглядит так: \\\\s+.

Java не имеет сырых (или стенографических) строк, поэтому вам нужно избежать обратного слэша, поэтому в regex engine он будет рассматривать его как двойную обратную косую черту. Это должно решить проблему добавления s+ вместо ваших пробелов.

При вводе регулярных выражений в коде это выглядит следующим образом:

\\\\s+ 
|  # Compile time 
V 
\\s+ 
|  # regex parsing 
V 
\s+ # actual regex used 

Обновленный мой ответ согласно @nhahtdh комментарий (фиксированное число)

обратной косой черты
+0

'' \ '' является частью строки замены, а не синтаксиса regex. '' \ '' просто используется для экранирования как для регулярного выражения, так и для строки замены. Другие языки (например, JavaScript) могут использовать '$' для escape '$', что позволяет избежать необходимости '' '' 'в качестве escape-символа в строке замены. – nhahtdh

+0

Спасибо за ответ и ясный порядок процесса! Теперь у меня есть намного лучшее понимание экранирования символов в Java. –

1

Вы должны использовать "\\\\s+" вместо "\\s+", поскольку \ является символом escape в regex replacement string syntax. Чтобы указать литерал \ в тексте для замены, вам нужно написать \\ в заменяющей строке, и это удваивается до "\\\\", так как \ требует экранирования в строковом литерале Java.

Обратите внимание, что \ просто используется как символ escape в синтаксисе строки замены регулярных выражений в Java. Другие языки, такие как JavaScript, используют $, чтобы избежать $, поэтому \ не нужно скрывать в строке замены регулярного выражения JavaScript.

Если вы заменяете матч с буквальным текстом, вы можете использовать Matcher.quoteReplacement, чтобы избежать иметь дело с побегом в регулярной выражении для замены строки:

String newSentence = tableSentence.replaceAll(" ", Matcher.quoteReplacement("\\s+")); 

В этом случае, поскольку вы ищете строку и заменить его с другой строкой, вы можете использовать вместо String.replace, что делает нормальную замену строки:

String newSentence = tableSentence.replace(" ", "\\s+"); 
+0

Спасибо за уведомление! Я ошибочно считал, что замена заменяет только первое вхождение (учитывая тот факт, что существует также «replaceAll»). Я должен был посмотреть на [этот ответ SO] (http://stackoverflow.com/questions/10827872/difference-between-string-replace-and-replaceall) раньше. –