Найти строки, в которых отсутствуют закрывающие скобки

Найти строки, в которых отсутствуют закрывающие скобки

Есть ли простой способ сделать это? В идеале, закрывающая скобка должна быть добавлена ​​в строку, в которой отсутствует скобка. Есть ли ответ SED/AWK?

Некоторые строки будут звучать так:

\url{http://google.com}

Пока другие:

\url{http://google.com

Я хотел бы добавить закрывающую фигурную скобку в те строки, которые содержат открывающую фигурную скобку, но не имеют закрывающей фигурной скобки.

%%%%% Исходный файл:

%\usepackage[anythingbreaks]{breakurl}
%\PassOptionsToPackage{hyphens}{url}\usepackage{hyperref}

%\usepackage[hyphens]{url}

\usepackage{url}
\urlstyle{rm}
\makeatletter
\g@addto@macro{\UrlBreaks}{\UrlOrds}
\makeatother


\title{}
\author{}
\date{2019-08-19}
%\sloppy
\begin{document}

решение1

Вы можете написать парсинг в Lua с использованием LPEG, который соответствует сбалансированным скобкам. Помните, что это основано на строках, т.е. если у вас есть конструкции, где скобки охватывают несколько строк, это не сработает.

test.lua

local lpeg = require("lpeg")
local P, S, V = lpeg.P, lpeg.S, lpeg.V

local function err(match, pos, cap)
    print(match, pos, cap)
end

local rule = P{"text",
    any = 1 - S"{}",
    balanced = "{" * (V"any" + V"balanced")^0 * "}",
    text = V"any" * (V"balanced" + V"any")^0 * P(-1)
}

local path = arg[1] or error("Usage: " .. arg[0] .. " <filename>")
local file = io.open(path, "r")

local n = 1
for line in file:lines() do
    local match = rule:match(line)
    if not match then
        error("Closing } missing on line " .. n)
    end
    n = n + 1
end

test.tex

\documentclass{article}
\usepackage{url}
\begin{document}
\url{http://google.com
\end{document}

Запуск этого с texluaдает

$ texlua test.lua test.tex
test.lua:21: Closing } missing on line 4

Также возможно автоматически добавить закрывающую скобку в проблемную строку. Для этого мы анализируем строку и, если она не пройдена, добавляем скобки в конце, пока она не будет пройдена успешно.

test2.lua

local lpeg = require("lpeg")
local P, S, V = lpeg.P, lpeg.S, lpeg.V

local function err(match, pos, cap)
    print(match, pos, cap)
end

local rule = P{"text",
    any = 1 - S"{}",
    balanced = "{" * (V"any" + V"balanced")^0 * "}",
    text = V"any" * (V"balanced" + V"any")^0 * P(-1)
}

local path = arg[1] or error("Usage: " .. arg[0] .. " <filename>")
local file = io.open(path, "r")

for line in file:lines() do
    local match
    while not match do
        match = rule:match(line)
        if not match then
            line = line .. "}"
        end
    end
    print(line)
end

У этого подхода есть некоторые очевидные ограничения, а именно: машина не может знатьгде именнонеобходимо поставить закрывающую скобку.

test2.tex

\documentclass{article}
\usepackage{url}
\begin{document}
Use \url{http://google.com to reach Google search
\end{document}

Выполнение приведенного выше примера дает синтаксически правильный, но семантически неверный вывод:

$ texlua test2.lua test2.tex
\documentclass{article}
\usepackage{url}
\begin{document}
Use \url{http://google.com to reach Google search}
\end{document}

Это не исправимо с помощью автоматизированного подхода. Только пользователь может знать, где должна быть размещена закрывающая скобка, чтобы быть семантически правильной.

решение2

Я заказал несколько программ для исправления проблемы. Две из них — программы Java. Одна — программа Javascript. Другая — скрипт Python. Вот ссылка: https://www12.zippyshare.com/v/9f8cIYpY/file.html

Программы Javascript и python работали у меня. Ваша удача с файлами Java зависит от природы файла, который вы пытаетесь исправить. Иногда в моем файле было два URL на одной строке, и это приводило к зависанию программ Java.

Возможно, именно по этой причине скрипт lua, предложенный @henrimenke, у меня не сработал.

Связанный контент