Мне нужно пропустить первые 20 строк из файла, которые начинаются с ###. (На самом деле 18 строк начинаются с ###, а две - с;).
Все, что я пробовал, не пропускает одни и те же две строчки - я понятия не имею, почему.
Вот что я пробовал (это только соответствующая часть моего кода):
elseif ($sourceformat == "Babylon") {
$line = fgets($source_file);
if ($line[0] === '#') {
continue;
}
if (strpos(trim($line), '#') === 0) {
continue;
}
if (substr($line, 0, 1) == "#") {
continue;
}
$source = trim(fgets($source_file));
if (empty($source)) {
continue;
}
$target = trim(fgets($source_file));
}
// then I proceed to writing the extracted terms into a new file that has a different format.
Я пробовал три вышеуказанных подхода по отдельности и все вместе ($line[0] === '#' и strpos(trim($line), '#') и substr($line, 0, 1) == '#') - но одна и та же строка всегда пропускается (не обнаруживается). Вот как выглядит весь раздел заголовка (это заголовок файла глоссария Babylon (. gls - но обычный текст).
### Glossary title:Cheeseus Muzik
### Author:Cheeseus
### Description:English - Bulgarian and Bulgarian - English glossary of musical terms
### Source language:Bulgarian
### Source alphabet:Cyrillic
### Target language:Bulgarian
### Target alphabet:Cyrillic
### Icon:
### Browsing enabled?Yes
### Type of glossary:00000000
### Case sensitive words?0
; DO NOT EDIT THE NEXT **SIX** LINES - Babylon-Builder generated text !!!!!!
### Glossary id:0265922f91878d6e846e9c869d8a89447c6e719e8585886b8692955f91887a9b8474859a85616a279a929ca07f6881507056895d6881304b5142515f42ba6c992e2b23828188719469656840908429504d595b486965418931312d5b47ad7843525650833a233a47514270695543449f31373b7179484e435a8c428827
### Confirmation string:8A148GOK
### File build number:0121DA07
### Build:80"0)2"0
### Glossary settings:00000000
### Gls type:00000001
; DO NOT EDIT THE PREVIOUS **SIX** LINES - Babylon-Builder generated text !!!!!!
### Glossary section:
a piacere
а пиачере, по желание
a tempo
а темпо, завръщане към основното темпо след отклонение
ad libitum
ат либитум, свободно, по желание
adagio
адажио (бавно)
allargando
аларгандо, забавяне
allegretto
алегрето, весело, бързичко
allegro
алегро, бързо, весело
allentando
алентандо, със забавяне
... (this is the actual glossary – source term on one line, target term on the next, followed by an empty line, then again source term, target term, new line. I only want these lines, while discarding (omitting, removing) the glossary header lines above. The code I have successfully removes all lines starting with # but this one below (the glossary ID), and it also removes the two lines starting with a semi-colon.
Это строка, от которой я не могу избавиться:
### Glossary id:0265922f91878d6e846e9c869d8a89447c6e719e8585886b8692955f91887a9b8474859a85616a279a929ca07f6881507056895d6881304b5142515f42ba6c992e2b23828188719469656840908429504d595b486965418931312d5b47ad7843525650833a233a47514270695543449f31373b7179484e435a8c428827
Я подозреваю, что это потому, что эта строка довольно длинная (или может быть потому, что предыдущая строка начинается с точки с запятой?). Я пробовал указать макс. длина в байтах для каждой строки, читаемой в fgets:
$line = fgets($source_file, 8192);
Но и это не сработало. Надеюсь, ты сможешь помочь.
Весь код слишком длинный, чтобы помещать его сюда, и он уже работает нормально - за исключением того, что избавился от этой единственной строки.
РЕШЕНИЕ (на основе ответа @Mehdi Bounya)
Похоже, я не выполнял проверки, которые у меня уже были, в нужном месте. Вот код, который делает именно то, что мне нужно:
elseif ($sourceformat == "Babylon") {
if ($targetformat == "Wordfast") {
$converted_source_target_delimiter = "\t";
$converted_term_delimiter = "\r\n";
}
$source = trim(fgets($source_file));
if (empty($source)) {
continue;
}
if ($source[0] === '#') {
continue;
}
if ($source[0] === ';') {
continue;
}
$target = trim(fgets($source_file));
}
$exported_entry = $source.$converted_source_target_delimiter.$target.$converted_term_delimiter;
Спасибо всем, кто предложил помощь!
Я пробовал это, не уверен, что правильно, я действительно не знаю, как писать регулярное выражение, получил это из другого сообщения: if (preg_match_all("/^#(.*)$/m", $line)) { continue; }, но проблема сохраняется, все строки начинаются с # и; удаляются (пропускаются) кроме строки ### Glossary id:....






Вы можете открыть файл с помощью fopen и перебрать строки, а затем просто проверить, начинается ли строка с нужного символа.
Эта функция принимает два параметра: $file - это путь к файлу, а $startWith - это массив символов, которые нужно пропустить:
function skipLines($file, $startWith = NULL){
$handle = fopen($file, "r");
if ($handle) {
while (($buffer = fgets($handle)) !== false) {
if (in_array($buffer[0], $startWith)){
// Your code if line starts with $startWith
} else {
// Your code if line does not start with $startWith
echo $buffer;
}
}
fclose($handle);
}
}
skipLines("sample.txt", ['#']); // Result 1
skipLines("sample.txt", [';']); // Result 2
skipLines("sample.txt", ['#', ';']); // Result 3
Результат 1:
; DO NOT EDIT THE NEXT **SIX** LINES - Babylon-Builder generated text !!!!!!
; DO NOT EDIT THE PREVIOUS **SIX** LINES - Babylon-Builder generated text !!!!!!
Результат 2:
### Glossary title:Cheeseus Muzik
### Author:Cheeseus
### Description:English - Bulgarian and Bulgarian - English glossary of musical terms
### Source language:Bulgarian
### Source alphabet:Cyrillic
### Target language:Bulgarian
### Target alphabet:Cyrillic
### Icon:
### Browsing enabled?Yes
### Type of glossary:00000000
### Case sensitive words?0
### Glossary id:0265922f91878d6e846e9c869d8a89447c6e719e8585886b8692955f91887a9b8474859a85616a279a929ca07f6881507056895d6881304b5142515f42ba6c992e2b23828188719469656840908429504d595b486965418931312d5b47ad7843525650833a233a47514270695543449f31373b7179484e435a8c428827
### Confirmation string:8A148GOK
### File build number:0121DA07
### Build:80"0)2"0
### Glossary settings:00000000
### Gls type:00000001
### Glossary section:
Результат 3:
// Nothing...
Я тоже хочу пропустить строки, начинающиеся с точки с запятой. Но с кодом, который у меня уже есть, они каким-то образом пропускаются без явного указания. В любом случае предлагаемый вами код не отличается от того, что у меня уже есть: if ($ line [0] === '#') {continue; } И это не работает - те же две строчки остались.
Я сделал отдельный файл, удалив весь другой код (относящийся к различным форматам преобразования), чтобы я мог проверить ваше предложение. Это работает, но я также хочу избавиться от строк, начинающихся с точки с запятой. Полагаю, можно просто добавить еще один if ($buffer[0] === ';').
@cheeseus Проверьте обновленный ответ, чтобы лучше проверить наличие нескольких символов.
Спасибо @Mehdi Bounya!
Подобно ответу @Mehdi Bounya выше, этот код сохранит все строки, отличные от #, в массив. Сравнение также выполняется с использованием функции substr в качестве альтернативы.
$correct_lines = [];
$handle = fopen("logs.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (substr($line, 0, 1) !== "#") {
array_push($correct_lines, $line);
}
}
fclose($handle);
} else {
echo "Error opening the file";
}
foreach ($correct_lines as $line) {
echo $line;
// ; DO NOT EDIT THE NEXT **SIX** LINES - Babylon-Builder generated text !!!!!!
// ; DO NOT EDIT THE PREVIOUS **SIX** LINES - Babylon-Builder generated text !!!!!!
}
Строки, начинающиеся с точки с запятой, тоже не нужны. Строки, начинающиеся с # и начинающиеся с; все являются частью заголовка глоссария. Я хочу удалить их все и продолжить чтение фактического глоссария, который затем преобразовываю в другой формат. Я отредактирую свой исходный вопрос, чтобы добавить большую часть файла и моего кода.
Вы можете использовать регулярное выражение regex101.com/r/LILbTu/1. Для
#или;используйте класс символов[;#].