Регулярное выражение для перехвата индекса строки листа Excel, исключая имя листа, имеющее цифру и другие цифры

Это мой первый вопрос о StackOverflow. :)

Я работаю с файлом Excel, мне нужно дублировать формулы в каждой строке, поэтому мне нужно менять индексы строк в этих формулах для каждой новой строки. Для этого я написал регулярное выражение, чтобы уловить индекс строки листа в формуле, исключая другие цифры, не относящиеся к индексу строки (например: «=2024-17-04») и исключая имя листа, имеющее цифры (например: «MATMAS05») .

Это работает очень хорошо, за исключением части «исключение имени листа, имеющего цифры».

Я написал это регулярное выражение: [A-Z]((?!MATMAS05)|(?<!"))+(\d+)(?!").
И у меня есть примеры формул, в которых индекс строки, который нужно поймать, равен 5:

SI(F5 = "";"";"Z_PACK_TYPE")
MARKET!A5
MARKET!MQ5
MARKET!AB5
MARKET!TX5
MARKET!SX5
MATMAS05!CZ5 = "3200";MARKET!DA5
SI(MATMAS05!CZ5 = "3200";MATMAS05!CZ5 = "3200";MARKET!DA5;"")
SI(L5 = "";"";"STRING")
SI(MATMAS05!CZ5 = "3300";MARKET!DA5;"")
SI(ESTVIDE(MARKET!EG5);"";SI(MATMAS05!CZ5 = "3200";MARKET!EG5;""))

Чтобы проверить свое регулярное выражение, я создал сохранение regex101, которым делюсь с вами соответствующим regex101.

Но, как вы можете видеть, мое регулярное выражение также улавливает цифру «5» в имени моего листа «MATMAS05».
Я хотел бы исключить имя листа «MATMAS05» из моих уловов.

Знаете ли вы, чего не хватает в моем регулярном выражении для этой цели?

Я думаю, вам просто нужно ![A-Z]+(\d+), см. regex101.com/r/PHCBkF/4. Если все ваши ссылки содержат имена листов, это сработает.

Wiktor Stribiżew 17.04.2024 09:47

Если внутри кавычек есть ложные срабатывания, в 99,9% случаев вам может сойти с рук "[^"]*(?:""[^"]*)*"|![A-Z]+(\d+)

Wiktor Stribiżew 17.04.2024 09:50

@WiktorStribiżew Я забыл добавить еще один пример формулы, внутри которого нет имени листа. В этом случае ![A-Z]+(\d+) не работает.

NicolasC 17.04.2024 09:54

Попробуйте regex101.com/r/PHCBkF/6, значение группы 1 — это то, что вам нужно.

Wiktor Stribiżew 17.04.2024 09:59

Это странно, потому что кажется, что оно работает хорошо, когда я смотрю на регулярное выражение101, но я пробую его на PHP-коде с предварительным совпадением, скрипт не всегда находит номер индекса строки. Вы можете увидеть это в этом онлайн-сохраненном скрипте onlinephp.io/c/c2fd6 Хорошо обрабатываются только формулы без имен листов, в остальных случаях функция preg_match возвращает только имя листа. Ты знаешь почему?

NicolasC 17.04.2024 14:05

Итак, вы делаете это на PHP, отлично. Попробуйте $regex = '/(?:(?<!")(?:"")*"[^"]*(?:""[^"]*)*"|\w+!)(*SKIP)(*F)|\b[A-‌​Z]+\K\d+\b/';, если вам нужно вернуть только цифры. Если вам нужно получить ВСЕ совпадения, используйте preg_match_all($regex, $formula, $matches);

Wiktor Stribiżew 17.04.2024 14:38

Посмотрите эту скрипку.

Wiktor Stribiżew 17.04.2024 14:40

Это то, что вы ищете: https://regex101.com/r/W99ncx/1 ?

Dunois 17.04.2024 15:06

@Dunois С помощью этого регулярного выражения ячейка L5 ( SI(L5 = "";"";"Z_LIFE_CYCLE_SG") не перехватывается. Мне нужно заранее поймать индекс строки с именем листа и без него, чтобы увеличить его в формуле для моей следующей строки.

NicolasC 18.04.2024 09:07

А моя рабочий пример? Вы это видели?

Wiktor Stribiżew 18.04.2024 11:26

@NicolasC, тогда просто сделайте регулярное выражение более конкретным, например: https://regex101.com/r/anTyqH/1 . Если CZ5 в SI(MATMAS05!CZ5 = "3200";MATMAS05!CZ5 = "3200";MARKET!DA5;"") также необходимо захватить вместе с DA5, используйте что-то вроде этого: https://regex101.com/r/ThbdM7/1 .

Dunois 18.04.2024 15:57

Пожалуйста, также посмотрите решение @WiktorStribiżew. Он реализован в PHP и, похоже, делает именно то, что вам нужно.

Dunois 18.04.2024 16:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
12
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать

<?php
// Enter your code here, enjoy!
$formulas = [
    'SI(F5 = "";"";"Z_PACK_TYPE")',
    'MARKET!A5',
    'MARKET!MQ5',
    'MARKET!AB5',
    'MARKET!TX5',
    'MARKET!SX5',
    'MATMAS05!CZ5 = "3200";MARKET!DA5',
    'SI(MATMAS05!CZ5 = "3200";MATMAS05!CZ5 = "3200";MARKET!DA5;"")',
    'SI(L5 = "";"";"STRING")',
    'SI(MATMAS05!CZ5 = "3300";MARKET!DA5;"")',
    'SI(ESTVIDE(MARKET!EG5);"";SI(MATMAS05!CZ5 = "3200";MARKET!EG5;""))',
];

$regex = '/(?:(?<!")(?:"")*"[^"]*(?:""[^"]*)*"|\w+!)(*SKIP)(*F)|\b[A-Z]+\K\d+\b/';

foreach ($formulas as $formula) {
    preg_match_all($regex, $formula, $matches);
    var_dump($matches);
}

Посмотрите демонстрацию PHP.

Регулярное выражение

(?:(?<!")(?:"")*"[^"]*(?:""[^"]*)*"|\w+!)(*SKIP)(*F)|\b[A-Z]+\K\d+\b

Посмотрите демонстрацию регулярных выражений . Подробности:

Подробности:

  • (?:(?<!")(?:"")*"[^"]*(?:""[^"]*)*"|\w+!)(*SKIP)(*F) - совпадения и пропуски:
    • (?<!")(?:"")*"[^"]*(?:""[^"]*)*" — подстрока между двумя символами " с экранированной кавычкой " внутри
    • | - или
    • \w+! — один или несколько символов слова, а затем символ !.
  • | - или
  • \b[A-Z]+\K\d+\b — граница слова, одна или несколько заглавных букв ASCII, \K опускает совпадающие символы, а затем сопоставляются и используются одна или несколько цифр, за которыми следует граница слова.

Спасибо @wiktor-stribiżew. Ваша формула работает идеально. 👌 Спасибо за быструю и эффективную помощь.🙏

NicolasC 30.04.2024 16:13

Другие вопросы по теме

Регулярное выражение для L = {w|w не содержит подстроки 110} в алфавите Σ = {0,1}
Как разбить непрерывную шестнадцатеричную строку на шестнадцатеричные блоки, разделенные пробелами, по 32 кортежа в каждом?
Я пытаюсь сопоставить заголовки разделов в документах PDF, но в некоторых случаях это не удается
Удалите соответствующие квадратные скобки, но только те, которые не имеют пробела внутри скобки
ReactJS – замена первого вхождения строкового шаблона пользовательским компонентом
Регулярное выражение Java, как получить версию из строки?
Регулярное выражение для удаления начальных и конечных круглых скобок внутри невложенного тега
Есть ли способ захватить целые ссылки Википедии?
Нужна помощь в сопоставлении строки с использованием регулярного выражения до последнего появления открывающей-закрывающей скобки с необязательным значением в открывающей-закрывающей скобке
Почему Java java.util.regex Pattern Matcher выдает исключения времени выполнения?