Регулярное выражение для обнаружения точки с запятой завершило C++ для и циклы с условием продолжения

Основной частью этого примера программы является использование собственного редактора ячеек EpisodeEditor. Он динамически определяет «эпизоды» на основе «серий», выбранных в первом столбце.

(Я использовал фиктивный источник данных для этой демонстрации.)

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import java.util.*;

public class ComboBoxTable
{
  public static void main(String[] args)
  {
    // Mock data source
    DataSource dataSource = new DataSource();

    JComboBox<String> seriesComboBox = new JComboBox<>();
    for (String s : dataSource.getSeries())
    {
      seriesComboBox.addItem(s);
    }

    JTable table = new JTable(
        new String[][] {{"", ""}, {"", ""}, {"", ""}},
        new String[] {"Series", "Episode"});
    table.getColumn("Series").setCellEditor(new DefaultCellEditor(seriesComboBox));
    table.getColumn("Episode").setCellEditor(new EpisodeEditor(dataSource));

    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(new JScrollPane(table));
    f.setBounds(300, 200, 400, 300);
    f.setVisible(true);
  }
}

class EpisodeEditor extends AbstractCellEditor implements TableCellEditor
{
  private DataSource dataSource;
  private JComboBox<String> episodesComboBox = new JComboBox<>();

  EpisodeEditor(DataSource dataSource)
  {
    this.dataSource = dataSource;
  }

  @Override
  public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
                                                        int row, int column)
  {
    String series = (String) table.getModel().getValueAt(row, 0);

    List<String> episodes = dataSource.getEpisodes(series);
    episodesComboBox.removeAllItems();
    for (String ep : episodes)
    {
      episodesComboBox.addItem(ep);
    }
    episodesComboBox.setSelectedItem(value);
    return episodesComboBox;
  }

  @Override
  public Object getCellEditorValue()
  {
    return episodesComboBox.getSelectedItem();
  }
}

class DataSource
{
  List<String> getSeries()
  {
    return Arrays.asList("Prison Break", "Breaking Bad", "Pokemon");
  }

  List<String> getEpisodes(String series)
  {
    switch (series)
    {
      case "Prison Break":
        return Arrays.asList("Break 1", "Break 2", "Break 3");
      case "Breaking Bad":
        return Arrays.asList("Bad 1", "Bad 2", "Bad 3");
      case "Pokemon":
        return Arrays.asList("P1", "P2", "P3");
      default:
        throw new IllegalArgumentException("Invalid series: " + series);
    }
  }
}
34
задан Peter Mortensen 25 January 2010 в 23:24
поделиться

8 ответов

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

  • Набор счетчик положения pos так, чтобы были точки к незадолго до открывающей скобки после Вашего for или while.
  • Набор открытый счетчик скобок openBr к 0.
  • Теперь продолжают увеличивать pos, читая символы в соответствующих положениях, и увеличивают openBr, когда Вы видите открывающую скобку и постепенно уменьшаете ее, когда Вы видите закрывающую скобку. Это увеличит его однажды вначале для первой открывающей скобки в" for (", инкремент и постепенно уменьшает еще немного для некоторых промежуточных скобок, и задерживает его к 0, когда Ваш for скобка закрывается.
  • Так, остановитесь, когда openBr будет 0 снова.

останавливающееся положение является Вашей закрывающей скобкой [1 112]. Теперь можно проверить, существует ли точка с запятой после или нет.

111
ответ дан Frank 27 November 2019 в 15:51
поделиться

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

, Если это - все, которое Вы ищете, Вам определенно не нужен полноценный лексический анализатор/синтаксический анализатор грамматики C++. Если Вы хотите практику, можно записать немного рекурсивно-достойного синтаксического анализатора, но даже это - слишком для просто парных скобок.

21
ответ дан Jesse Beder 27 November 2019 в 15:51
поделиться

Это - яркий пример использования неправильного инструмента для задания. Регулярные выражения не обрабатывают произвольно вложенные подсоответствия очень хорошо. Что необходимо сделать, вместо этого использование реальный лексический анализатор, и синтаксический анализатор (грамматику для C++ должно быть легко найти), и ищите неожиданно пустые тела циклов.

8
ответ дан Greg Hewgill 27 November 2019 в 15:51
поделиться

Я даже не обратил бы внимание на содержание parens.

Просто соответствие любая строка, которая запускается с for и заканчивается точкой с запятой:

^\t*for.+;$

, Если Вы не имеете for разделение операторов по поводу нескольких строк, которые будут хорошо работать?

2
ответ дан Peter Boughton 27 November 2019 в 15:51
поделиться

Попробуйте этот regexp

^\s*(for|while)\s*
\(
(?P<balanced>
[^()]*
|
(?P=balanced)
\)
\s*;\s

, в который я удалил обертывание \( \) приблизительно (?P=balanced) и переместился * позади любого не paren последовательность. Я имел эту работу с повышением xpressive и перепроверил что веб-сайт ( Xpressive) для обновления моей памяти.

2
ответ дан Bill Perkins 27 November 2019 в 15:51
поделиться

Greg абсолютно корректен. Этот вид парсинга не может быть сделан с регулярными выражениями. Я предполагаю, что возможно создать некоторое ужасающее чудовище, которое работало бы на многие случаи, но затем Вы будете просто натыкаться на что-то, что делает.

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

1
ответ дан Foredecker 27 November 2019 в 15:51
поделиться

Я не знаю, что regex обработал бы что-то как этот очень хорошо. Попробуйте что-то вроде этого

line = line.Trim();
if(line.StartsWith("for") && line.EndsWith(";")){
    //your code here
}
1
ответ дан Malfist 27 November 2019 в 15:51
поделиться

Другая мысль, которая игнорирует круглые скобки и рассматривает for как конструкция, содержащая три разграниченных точкой с запятой значения:

for\s*\([^;]+;[^;]+;[^;]+\)\s*;

Эта опция работы, даже когда разделено по нескольким строкам (после того как МУЛЬТИЛИНИЯ включила), но предполагает, что for ( ... ; ... ; ... ) единственная допустимая конструкция, так не работал бы с for ( x in y ) конструкция или другие отклонения.

Также предполагает, что нет никаких функций, содержащих точки с запятой как аргументы, такие как:

for ( var i = 0; i < ListLen('a;b;c',';') ; i++ );

, Является ли это вероятным случаем, зависит от того, для чего Вы на самом деле делаете это.

1
ответ дан Peter Boughton 27 November 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: