Как распарсить вордовский файл?

nik93

Есть вордовский файл с таблицей. В этой таблице есть столбец с информацией которую нужно распарсить в эксель. Пример одной из ячеек столбца:
ГОСТ 8.113-85 ГСИ. Штанген-циркули. Методы и средства по-верки.
МИ 2196-92 ГСИ Штангенглуби-номеры. Методика поверки.
МИ 1384-86 ГСИ. Штангенциркуль со стрелочным отсчетом. Методика поверки.
МИ 2190-92. ГСИ. Штангенрейс-массы. Методика поверки

из этой ячейки нужно перенести в первую колонку экселя МИ|ГОСТ, во вторую колонку номер, в третью всю оставщуюся часть до нового МИ, ГОСТ или до конца ячейки
т.е. на выходе должно получиться нечто такое:
ГОСТ   |   8.113-85   |    ГСИ. Штанген-циркули. Методы и средства по-верки.
МИ | 2196-92 | ГСИ Штангенглуби-номеры. Методика поверки.
...

чем это удобнее всего сделать, куда копать?

anton7805

регулярными выражениями :) В с# они есть

nik93

лучше на VBA, чтобы не заморачиваться на доковский формат.

Dasar

сохранить как docx, а дальше с помощью xpath-запросов выдернуть все что нужно.

oleg701

Окстись, какой парсинг.
Данные - текст по столбцам в Excel.
Если структура такая, как ты описываешь, то найдешь способ разбить правильно.

nik93

Если структура такая, как ты описываешь, то найдешь способ разбить правильно.
со структурой все плохо, единственное что гарантируется, это то что новый блок информации начинается с "МИ". Сделал так, чтобы нужная инфа сливалась из вордовского файла в строку.
теперь мне нужно разбить эту строку на множество строк по МИ, чтобы из
"МИ 1384-86 ГСИ. Штангенциркуль со стрелочным отсчетом. Методика поверки. МИ 2190-92. ГСИ. Штангенрейс-массы. Методика поверки"
получилось две строки:
"МИ 1384-86 ГСИ. Штангенциркуль со стрелочным отсчетом. Методика поверки."
"МИ 2190-92. ГСИ. Штангенрейс-массы. Методика поверки"
но не получается :( (C#). Если парсю
МИ.*  

то один матч, куда запихивается всё, если
МИ.*?  

то два матча "МИ" и "МИ".
остается только сплитануть по МИ и к каждой строке потом это МИ приписать, но коряво,
может всетаки как-то можно это сделать матчами?

apl13

Штангенглуби-номеры
Правильно говорить: "Штангенглуби-номера"! :mad:

pitrik2

чем парсишь?
хотя пофиг, там по любому есть команда split
которой просто "МИ" передаешь

nik93

которой просто "МИ" передаешь
я выше написал - в получаемых строках это МИ удаляется, так не хочется.
пользую Regex.

pitrik2

я выше написал - в получаемых строках это МИ удаляется, так не хочется.
ну добавь его потом туда
даже если так делать split гораздо проще чем с регэкспами возиться
добавлять МИ надо ко всем строкам, только для первой надо отельно проверить нужен ли он

pitrik2

может всетаки как-то можно это сделать матчами?
ну видимо так
(МИ.*)*
дальше надо пробежаться по матчеру и вытащить все group(1)

nik93

ну видимо так
(МИ.*)*
дальше надо пробежаться по матчеру и вытащить все group(1)
не работает.

nik93

даже если так делать split гораздо проще чем с регэкспами возиться
почему еще сплит не устраивает - разделителей может быть несколько, и как потом понять куда что приписывать?

pitrik2

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

Pattern pattern = Pattern.compile("(MIM[^I])|([^M]*)");
// Matcher matcher = pattern.matcher("MIruMIr");
// Matcher matcher = pattern.matcher("MIruMoemuMIr");
Matcher matcher = pattern.matcher("vottakiedela MIruMoemuMIrIVAMtogoJEMIIru");
while (matcher.find {
System.out.println("c = " + matcher.group(0;
}

смысл такой: ищем MI плюс чтото, это чтото или не начинается на M или начинается на M но потом не идет I

nik93

смысл такой: ищем MI плюс чтото, это чтото или не начинается на M или начинается на M но потом не идет I
всего-то осталось запрогать еще 4 разделителя длиной от 2 до 4 символов :crazy:

nik93

сделал так:

string[] dels = re.Split(textBoxRegExp.Text);
List<string> resultsold = new List<string>
List<string> resultsnew = new List<string>
string tempstr = "многа букаф";
resultsold.Add(tempstr);
foreach (string del in dels)
{
re = new Regex(del);
foreach (string res in resultsold)
{
count = 0;
foreach (string str in re.Split(res
{
count++;
if (count != 1)
resultsnew.Add(del + str);
else
resultsnew.Add(str);
}
}
resultsold = resultsnew;
resultsnew = new List<string>
}

тоесть бью начальную строку разделителем, дописывая его в непервые строки, потом также бью получившиеся строки, пока разделители не кончатся. Ну и в конце при выводе проверять, чтобы в строке присутствовал хотябы 1 разделитель, иначе мусор.

Dasar

позанудствую...
если бы оно еще вот так бы, было оформлено, то вообще отлично было бы (не фига локальные переменные делать глобальными):
string[] dels = re.Split(textBoxRegExp.Text);
List<string> resultsold = new List<string>
string tempstr = "многа букаф";
resultsold.Add(tempstr);
foreach (string del in dels)
{
Regex re = new Regex(del);
List<string> resultsnew = new List<string>
foreach (string res in resultsold)
{
int count = 0;
foreach (string str in re.Split(res
{
count++;
if (count != 1)
resultsnew.Add(del + str);
else
resultsnew.Add(str);
}
}
resultsold = resultsnew;
}

pitrik2

resultsold
я бы енто еще на resultsOld заменил
ну и resultsNew аналогично

nik93

как всегда жжоте :grin: приму к сведению

nik93

не фига локальные переменные делать глобальными
это маханький кусок процедуры, там одни и еже переменные юзаются в разных местах :)

Dasar

это маханький кусок процедуры, там одни и еже переменные юзаются в разных местах
так вот именно за это и надо убивать.
потом же фиг разберешься - что именно в этой переменной должно храниться, и кто отвечает за ее правильное значение
Оставить комментарий
Имя или ник:
Комментарий: