Получение java.lang.StackOverflowError на String.replaceAll в Java - PullRequest
0 голосов
/ 09 мая 2018

Мне нужно заменить слово «ИЛИ» на «||»в данной строке.Его следует заменять только тогда, когда оно само является полным словом во входной строке.Кроме того, его не следует заменять, если он указан в кавычках.Например, если строка ввода

application.path = "EXCEL.exe" ИЛИ application.path = "EXCELSIOR.exe" ИЛИ application.path = "XYZ ИЛИ ABC.exe"

вывод должен быть

application.path = "EXCEL.exe" ||application.path = "EXCELSIOR.exe" ||application.path = "XYZ OR ABC.exe"

Обратите внимание, что ИЛИ в EXCELSIOR.exe и "XYZ OR ABC.exe" не заменяется.

Код Java, который я использую, выглядит следующим образом:

String inputStr = "(quote.AGE was 24 AND (application.path = \"**\\acad.exe\" OR application.path = \"**\\dxfdwg.exe\" OR application.path = \"**\\EXCELSIOR.EXE\" OR application.path = \"**\\iges.exe\" OR application.path = \"**\\notepad.exe\" OR application.path = \"**\\run_journal.exe\" OR application.path = \"**\\AcroRd32.exe\" OR application.path = \"**\\dllhost.exe\" OR application.path = \"**\\powerpnt.exe\" OR application.path = \"**\\Edge.exe\" OR application.path = \"**\\step203ug.exe\" OR application.path = \"**\\step214ug.exe\" OR application.path = \"**\\VisView.exe\" OR application.path = \"**\\Teamcenter.exe\" OR application.path = \"**\\ug_convert_part.exe\" OR application.path = \"**\\ugraf.exe\" OR application.path = \"**\\ugtopv.exe\" OR application.path = \"**\\wmplayer.exe\" OR application.path = \"**\\winword.exe\" OR application.path = \"**\\wordpad.exe\" OR application.path = \"**\\vlc.exe\" OR application.path = \"**\\dwgviewr.exe\" OR application.name = \"RMS\" OR application.path = \"**\\acrobat.exe\" OR application.path = \"**\\Alias.exe\" OR application.path = \"**\\awtessd.exe\" OR application.path = \"**\\proe.exe\" OR application.path = \"**\\STPViewer.exe\" OR application.path = \"**\\gom_inspect.exe\" OR application.path = \"**\\gom_cad_server2.exe\" OR application.path = \"**\\sldworks.exe\" OR application.path = \"**\\sldworks_fs.exe\" OR application.path = \"**\\sldProcMon.exe\" OR application.path = \"**\\AdapplicationMgr.exe\" OR application.path = \"**\\AdapplicationMgrSvc.exe\" OR application.path = \"**\\SE3Dtrans.exe\" OR application.path = \"**\\stamp.exe\" OR application.path = \"**\\psolid.exe\" OR application.path = \"**\\mpid.exe\" OR application.path = \"**\\mpirun.exe\" OR application.path = \"**\\FS.exe\" OR application.path = \"**\\xtop.exe\" OR application.path = \"**\\pro_comm_msg.exe\" OR application.path = \"**\\nmsd.exe\" OR application.path = \"**\\creoagent.exe\" OR application.path = \"**\\parametric.exe\" OR application.path = \"**\\PDFEditor.exe\" OR application.path = \"**\\CNEXT.exe\" OR application.path = \"**\\drafter.exe\" OR application.path = \"**\\convert.exe\" OR application.path = \"**\\ActCut3D.exe\" OR application.path = \"**\\ppcbasic.exe\" OR application.path = \"**\\deltamesh_stamping.exe\" OR application.path = \"Xasfsf\" OR application.path = \"sfdsdf\"))";
String replacedStr = inputStr.replaceAll("(?m)\\bOR\\b(?=(?:\"[^\"]*\"|[^\"])*$)", "||");

Это прекрасно работает для более коротких строк, но как только длина превышает 2000 символов, выдается следующая ошибка:

Исключение в потоке "main" java.lang.StackOverflowError в java.util.regex.Pattern $ BmpCharProperty.match (Pattern.java:3796) в java.util.regex.Pattern $ Branch.match (Pattern.java:4604) в java.util.regex.Pattern $ GroupHead.match (Pattern.java:4658) в java.util.regex.Pattern $ Loop.match (Pattern.java:4785) в java.util.regex.Pattern $ GroupTail.match (Pattern.java:4717) в java.util.regex.Pattern $ BranchConn.match (Pattern.java:4568) в java.util.regex.Pattern $ CharProperty.match (Pattern.java:3777) в java.util.regex.Pattern $ Branch.match (Pattern.java:4604)

Я читаю в некоторых других темах ( thread1 , thread2 ) что Java не очень хорошо обрабатывает регулярные выражения для длинных строк.Может кто-нибудь предложить, как я могу улучшить свое регулярное выражение, чтобы избежать StackOverflowError?

1 Ответ

0 голосов
/ 09 мая 2018

Может кто-нибудь предложить, как я могу улучшить свое регулярное выражение, чтобы избежать StackOverflowError

Да, я могу дать вам два решения, вам просто нужно посмотреть на вашу проблему с другой стороны.

Вот краткий анализ вашей проблемы и быстрое решение, вы можете использовать это регулярное выражение вместо (.*?\"\s+)\bOR\b(\s+application.*?):

Решение одно

String inputStr = //that long String
String regex = "(.*?\"\\s+)\\bOR\\b(\\s+application.*?)";
String replacedStr = inputStr.replaceAll(regex, "$1||$2");

System.out.println(replacedStr);

Я заметил, что ИЛИ, которое вы хотите заменить, существует после " ans space OR * application, мое регулярное выражение будет соответствовать этому ИЛИ и заменять его.

Вывод для короткого примера, он даст вам тот же результат для длинного:

application.path="EXCEL.exe" || application.path="EXCELSIOR.exe" || application.path="XYZ OR ABC.exe"
                             ^^                          ^^      ^^                       ^^

Решение два

Если вы используете Java 9+, вы можете использовать это регулярное выражение application.path=(\"(.*?)\"), чтобы сопоставить каждую вещь, такую ​​как application.path="something here", собрать результат с ||

String regex = "application.path=(\"(.*?)\")";
String text = Pattern.compile(regex)
        .matcher(inputStr).results().map(MatchResult::group)
        .collect(Collectors.joining(" || "));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...