Author Topic: Question about regex flavor  (Read 9701 times)

Offline bigbug

  • Multiple posting newcomer
  • *
  • Posts: 39
Question about regex flavor
« on: December 07, 2006, 12:04:17 pm »
Is there any way to use non-greedy quantifiers in search/replace/testbed?
As you surely know, in wxWidgets there are different flavors of regular expressions. Why doesn't Code::Blocks use the advanced flavor in search/replace/testbed?

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Question about regex flavor
« Reply #1 on: December 07, 2006, 12:53:28 pm »
Why doesn't Code::Blocks use the advanced flavor in search/replace/testbed?
I believe because advanced isn't POSIX. But it (of course) can be easily implemented.
With regards, Morten
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Question about regex flavor
« Reply #2 on: December 07, 2006, 02:11:18 pm »
Is there any way to use non-greedy quantifiers in search/replace/testbed?
Unluckily, no.

As you surely know, in wxWidgets there are different flavors of regular expressions. Why doesn't Code::Blocks use the advanced flavor in search/replace/testbed?
Code::Blocks is build in Unicode mode (unless you explicitely specify otherwise), so in fact it uses the "builtin" library (at least, that's what the wxWidgets documentation claims). Under Windows, it should even use the builtin library in ANSI builds.

However, as usual, there is a lot of blah blah about nothing. The "builtin" library with its "advanced" functions does nothing but plain normal extended POSIX. If you attempt to use any of the "advanced" functions, you get a regex compile error.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Question about regex flavor
« Reply #3 on: December 07, 2006, 02:15:02 pm »
If you attempt to use any of the "advanced" functions, you get a regex compile error.
I think he doesn't mean to change the regex flavour of C::B but only for the regex testbed plugin -> thus make it configurable to enable tests against whatever your favorite regex is (which would make sense though...). Of course this applies to wxRegEx only then... maybe... ;-)
...but I'm not sure if I got that part right.
With regards, Morten.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline bigbug

  • Multiple posting newcomer
  • *
  • Posts: 39
Re: Question about regex flavor
« Reply #4 on: December 07, 2006, 02:55:55 pm »
Since the "advanced" flavor is a superset of POSIX, why not use it?
I've done a test by modifying the minimal wx example. It really fails with the default flag "wxRE_EXTENDED", but it works like a charm, if I use the method "Compile" with "wxRE_ADVANCED". Here is the source of the test:
Code: [Select]
#include <wx/wx.h>
#include <wx/regex.h>
#include "mondrian.xpm"

const unsigned int wxID_TEST_REGEX  = wxID_HIGHEST + 1;

// Declare the application class
class MyApp : public wxApp
{
public:
    // Called on application startup
    virtual bool OnInit();
};

// Declare our main frame class
class MyFrame : public wxFrame
{
public:
    // Constructor
    MyFrame(const wxString& title);

    // Event handlers
    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
    void OnTestRegEx(wxCommandEvent& event);

private:
    // This class handles events
    DECLARE_EVENT_TABLE()
};

// Give wxWidgets the means to create a MyApp object
IMPLEMENT_APP(MyApp)

// Implements MyApp& wxGetApp()
DECLARE_APP(MyApp)

bool MyApp::OnInit()
{
    // Create the main application window
    MyFrame *frame = new MyFrame(wxT("Minimal wxWidgets App"));

    // Show it
    frame->Show(true);

    // Start the event loop
    return true;
}

MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
    // Set the frame icon
    SetIcon(wxIcon(mondrian_xpm));

    // Create a menu bar
    wxMenu *fileMenu = new wxMenu;

    // The "About" item should be in the help menu
    wxMenu *helpMenu = new wxMenu;
    helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"),
                     wxT("Show about dialog"));

    fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"),
                     wxT("Quit this program"));

    fileMenu->Append(wxID_TEST_REGEX, wxT("&Test wxRegEx"),
                     wxT("Test wxRegEx"));

    // Now append the freshly created menu to the menu bar...
    wxMenuBar *menuBar = new wxMenuBar();
    menuBar->Append(fileMenu, wxT("&File"));
    menuBar->Append(helpMenu, wxT("&Help"));

    // ... and attach this menu bar to the frame
    SetMenuBar(menuBar);

    // Create a status bar just for fun
    CreateStatusBar(2);
    SetStatusText(wxT("Welcome to wxWidgets!"));
}


// Event table for MyFrame
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
    EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
    EVT_MENU(wxID_TEST_REGEX, MyFrame::OnTestRegEx)
END_EVENT_TABLE()


void MyFrame::OnAbout(wxCommandEvent& event)
{
    wxString msg;
    msg.Printf(wxT("Hello and welcome to %s"),
               wxVERSION_STRING);

    wxMessageBox(msg, wxT("About Minimal"),
                 wxOK | wxICON_INFORMATION, this);
}

void MyFrame::OnTestRegEx(wxCommandEvent& event)
{
    wxString s = wxT("ababcbab");
    wxRegEx rxTest;
    if(!rxTest.Compile(wxT("(.*?)c"), wxRE_ADVANCED))
        wxMessageBox(wxT("Compilation failed"), wxT("Error"),
                 wxOK | wxICON_ERROR, this);
    else
    {
        rxTest.Replace(&s, wxT("\\1"));
        wxMessageBox(s, wxT("Success"),
                 wxOK | wxICON_INFORMATION, this);
    }
}

void MyFrame::OnQuit(wxCommandEvent& event)
{
    // Destroy the frame
    Close();
}
Edit:
Sorry, I forgot to say, what system and wx versions I used for the test:
Windows XP SP2
wxWidgets-2.6.3 (unicode-monodll)
wxWidgets-2.8.0 RC1 (unicode-monodll)

The test is maybe more clear by using the following code (it will get all befor the first "c", i. e. "abab"):
Code: [Select]
    wxString s = wxT("ababcbacab");
    wxRegEx rxTest;
    if(!rxTest.Compile(wxT("(.*?)c.*$"), wxRE_ADVANCED))
        wxMessageBox(wxT("Compilation failed"), wxT("Error"),
                 wxOK | wxICON_ERROR, this);
    else
    {
        rxTest.Replace(&s, wxT("\\1"));
        wxMessageBox(s, wxT("Success"),
                 wxOK | wxICON_INFORMATION, this);
    }
« Last Edit: December 07, 2006, 03:18:30 pm by bigbug »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Question about regex flavor
« Reply #5 on: December 07, 2006, 04:01:10 pm »
but it works like a charm, if I use the method "Compile" with "wxRE_ADVANCED".
Well, again: All you need is a choicebox in the regex testbed plugin GUI and a simple switch case operation accordingly in the code. What's the problem?! ;-)
With regards, Morten.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline bigbug

  • Multiple posting newcomer
  • *
  • Posts: 39
Re: Question about regex flavor
« Reply #6 on: December 07, 2006, 04:53:14 pm »
But it could also be used in the search/replace dialog without any problems, couldn't it?
I think, moving from POSIX EREs to AREs isn't very hard at all:
Quote from: the wx manual
The only feature of AREs that is actually incompatible with POSIX EREs is that \ does not lose its special significance inside bracket expressions.

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Question about regex flavor
« Reply #7 on: December 07, 2006, 05:15:05 pm »
But it could also be used in the search/replace dialog without any problems, couldn't it?
I think, moving from POSIX EREs to AREs isn't very hard at all:
Quote from: the wx manual
The only feature of AREs that is actually incompatible with POSIX EREs is that \ does not lose its special significance inside bracket expressions.

the only problem is CB doesn't currently use the wxWidget's regex engine for Find and Replace, it uses Scintilla's internal regex engine. I've played around with adding support for wxregex in CBs search/replace, i will submit a patch soon if all goes well or others don't beat me to it. My main concern is whether the text locations reported by Scintilla's "find" method will match the text locations reported by wxRegex's "matches" method.

Offline bigbug

  • Multiple posting newcomer
  • *
  • Posts: 39
Re: Question about regex flavor
« Reply #8 on: December 07, 2006, 05:44:20 pm »
Quote from: dmoore
I've played around with adding support for wxregex in CBs search/replace, i will submit a patch soon if all goes well or others don't beat me to it.
That's nice :), I hope your patch will be accepted.

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Question about regex flavor
« Reply #9 on: December 07, 2006, 09:15:07 pm »
Patch:

http://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=1701&group_id=5358

After applying the patch, choose the "Advanced REGEX" checkbox from the Settings -> Editor menu and then check "Regular Expression" in the Find or Replace dialogs. Should work for Local Find/Replace as well as Find/Replace in files.

please test on a dummy project - if CB goes on a code eating rampage with this, don't say I didn't warn you.

NOTE: I'm use wxRE_ADVANCED with wxRE_NEWLINE in the regex compile statement. wxRE_NEWLINE supports ^ and $ for start beginning of lines (rather than start beginning of entire file).

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Question about regex flavor
« Reply #10 on: December 13, 2006, 04:58:53 am »
if anyone is willing to test, I've compiled Code::Blocks with this patch installed (as well as my interpreted languages plugins) at
http://prdownload.berlios.de/cbilplugin/CodeBlocks_unicode_rev3369_with_IL_plugins_Rev1.exe

as before, you must select "Use advanced regexes" in the editor settings control panel.

one thing to note, which may be different from what you might exepct, is that Advanced regex seem to be greedy even through newline characters (maybe I screwed up a setting)

Offline bigbug

  • Multiple posting newcomer
  • *
  • Posts: 39
Re: Question about regex flavor
« Reply #11 on: December 13, 2006, 09:57:33 am »
Hello,
I've done a quick test.
Quote from: dmoore
one thing to note, which may be different from what you might exepct, is that Advanced regex seem to be greedy even through newline characters (maybe I screwed up a setting)
For me it works as it should. It isn't greedy through newline characters, if I use a greedy quantifier it only applies to a line. For example a search for .* finds a line and you can go through each line by pressing F3. Maybe your End-of-line-mode is CR (i. e. \r). The End-of-line-mode can be changed in the Edit menu. If it is CR (like in Mac, I think), .* matches the whole document. But it matches a line if either CR&LF or LF is used. I've tested the non-greedy search also and it works great!

Thanks! :D

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Question about regex flavor
« Reply #12 on: December 13, 2006, 02:38:26 pm »
Maybe your End-of-line-mode is CR (i. e. \r).

whoops! I had just switched to testing out CR mode before I checked the regex feature again. I thought something was strange...  :oops:

thanks for testing bigbug