www.webdeveloper.com
Recent Articles
  • Finding Slow Running Queries in ASE 15
  • A More Advanced Pie Chart for Analysis Services Data
  • Adobe AIR Programming Unleashed: Working with Windows
  • Performance Testing SQL Server 2008's Change Data Capture Functionality
  • The ABC's of PHP: Introduction to PHP
  • How to Migrate from BasicFiles to SecureFiles Storage
  • Why the Twitter Haters Are Wrong
  • User Personalization with PHP: Beginning the Application
  • Whats in an Oracle Schema?
  • Lighting Enhancement in Photoshop
  •  

    Go Back   WebDeveloper.com > Client-Side Development > JavaScript

    JavaScript JavaScript (not Java) Discussion and technical support, including AJAX and frameworks (JQuery, MooTools, Prototype...)

    Reply
     
    Thread Tools Rate Thread Display Modes
      #1  
    Old 07-23-2010, 09:07 AM
    Kor's Avatar
    Kor Kor is offline
    Red Devil Moderator
     
    Join Date: Dec 2003
    Location: Bucharest, ROMANIA
    Posts: 12,658
    Interesting RegExp dilemma

    I have this kind of string, with a lot of parenthesis which might nest other parathesis, and so on:
    Code:
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    Now I want to use a regular expression to remove all the parenthesis along with the nested substrings. The text above should become:
    Code:
    var finalstr='Four score our fathers brought this continent';
    First thing which came up into mind was a non-greedy RegExp to match everything between paranthesis:
    Code:
    /\(.*?\)/g
    But that works only if there are no other inner parenthesis nested inside the parenthesis, so that:
    Code:
    str=str.replace(/\(.*?\)/g,'');
    returns
    'Four score ago) our fathers brought this continent'

    which is logical, as the replaced substrings are:

    'Four score ( and seven (years) ago) our fathers brought (forth onto) this continent'

    but this is not what I want.

    I can not see how could I replace the "most inner" \(.*?\) first, and repeat the process, "climbing" to the next "parent delimiters".

    Any ideas?

    Last edited by Kor; 07-23-2010 at 09:10 AM.
    Reply With Quote
      #2  
    Old 07-23-2010, 09:31 AM
    Kor's Avatar
    Kor Kor is offline
    Red Devil Moderator
     
    Join Date: Dec 2003
    Location: Bucharest, ROMANIA
    Posts: 12,658
    I think I found a way. I am not sure it is the best possible solve, but it works, as far as I have seen:
    Code:
    <script type="text/javascript">
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    while(str.match(/\(.*?\)/g)){
    str=str.replace(/\(.[^\(]*?\)/g,'');
    }
    </script>
    Sees anyone a better approach?
    Reply With Quote
      #3  
    Old 07-23-2010, 09:46 AM
    Declan1991 Declan1991 is offline
    Moderator
     
    Join Date: Aug 2007
    Posts: 3,427
    I remember having this exact same problem with tags. So if I nested tags with the same tag name (i.e. div), I couldn't separate on closing tag from another.

    The other problem I had was if you remove the outer most parentheses, (or inner), you have to do a separate replace for each level of parentheses. My solution was normally something like this.
    Code:
    str = str.replace(/\([^\(\)]*\)/g,"");
    But as I say, you need to repeat that on the string for each layer of parentheses. So this (excluding the fact that there are too many spaces left) would be my solution.
    Code:
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this 
    
    continent';
    var reg = /\([^\(\)]*\)/g;
    while (reg.test(str)) {
    str = str.replace(reg,"");
    }
    I feel there has to be a better, more elegant way, though. Perhaps not using regular expressions but iterating over the string and deleting characters would be better, an optomisied version of this in a function for example.
    Code:
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    var par = 0, retstring = "";
    for (var i = 0; i < str.length; i++) {
    if (str.charAt(i) == '(') {
    par++;
    }
    if (!par) {
    retstring+=str.charAt(i);
    }
    if (str.charAt(i) == ')') {
    par --;
    }
    }
    EDIT: You came to the same conclusion while I was writing.
    __________________
    Quote:
    Great wit and madness are near allied, and fine a line their bounds divide.
    Reply With Quote
      #4  
    Old 07-23-2010, 09:49 AM
    Kor's Avatar
    Kor Kor is offline
    Red Devil Moderator
     
    Join Date: Dec 2003
    Location: Bucharest, ROMANIA
    Posts: 12,658
    Yes, I came to the same conclusion. Thank you very much for your answer. I also think that sometimes JavaScript classical string methods could run faster than RegExp. But RegExp are soooo nice
    Reply With Quote
      #5  
    Old 07-23-2010, 09:54 AM
    Declan1991 Declan1991 is offline
    Moderator
     
    Join Date: Aug 2007
    Posts: 3,427
    I'm a sucker too. I get so sick of fiddling with strings (or character arrays finishing in '\0' if you insist ) in C sometimes, it's such a relief to come to JavaScript and be able to pass functions to String.replace!
    __________________
    Quote:
    Great wit and madness are near allied, and fine a line their bounds divide.
    Reply With Quote
      #6  
    Old 07-23-2010, 04:24 PM
    Ayşe Ayşe is offline
    enjoiningOfConstancy++;
     
    Join Date: Sep 2007
    Location: Türkiye
    Posts: 160
    Code:
    <script type="text/javascript">
    
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    
    var s = str.replace(/\(.*?(?:\(.*?\).*?)?\).*?/g,"");
    
    alert(s); // Four score our fathers brought this continent
    
    var m = str.match(/\(.*?(?:\(.*?\).*?)?\).*?/g);
    
    alert(m[0]); // (and seven (years) ago)
    
    alert(m[1]); // (forth onto)
    
    </script>
    __________________
    <div id="t" style="background-color: pink">The Time Through Ages. In the Name of Allah, Most Gracious, Most Merciful. 1. By the Time, 2. Verily Man is in loss, 3. Except such as have Faith, and do righteous deeds, and (join together) in the mutual enjoining of Truth, and of Patience and Constancy.</div>

    <script type="text/javascript">
    Math.PHI=(1+ Math.sqrt(5))/2;
    var r=Math.random()*161.8, h=161+r, el=document.getElementById("t").style;
    el.width=h*Math.PHI; el.height=h;
    </script>
    Reply With Quote
      #7  
    Old 07-23-2010, 05:47 PM
    rnd me's Avatar
    rnd me rnd me is offline
    working on the chain...
     
    Join Date: Jul 2008
    Location: urbana, il
    Posts: 1,808
    Code:
    
    function findBetween(A, B, str, charLimit) {
    	var opens = 0, closes = 0;
    	charLimit=charLimit||6000;
    	for (var i = 0; i < charLimit; i++) {
    	  var cc = str.charAt(i);
    	  if (cc === A) {
    		opens++;
    	  }
    	  if (cc === B) {
    		closes++;
    	  }
    	  if (opens && closes && opens <= closes) {
    		return [str.indexOf(A) - 1, i + 1];
    	  }
    	  if (!cc) {
    		return 0;
    	  }
    	}
    	return 0;
    }
    
    
    function censor(str){
       var last="";
       while(last!=str){
               var r=findBetween("(", ")", str);
               last=str;
               str=str.slice(0,r[0])+str.slice(r[1]);
       }
      return str
    }
    
    
    
    var str='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    var finalstr='Four score our fathers brought this continent';
    
    alert(censor(str) === finalstr) //==true
    Reply With Quote
      #8  
    Old 07-23-2010, 06:17 PM
    Declan1991 Declan1991 is offline
    Moderator
     
    Join Date: Aug 2007
    Posts: 3,427
    Ayşe's code is limited to a set number of parentheses deep. If you nest more than two it won't work properly.
    __________________
    Quote:
    Great wit and madness are near allied, and fine a line their bounds divide.
    Reply With Quote
      #9  
    Old 07-23-2010, 08:30 PM
    mrhoo mrhoo is offline
    Registered User
     
    Join Date: Feb 2006
    Posts: 2,709
    You may have already thought of this-
    its based on the 'inside- out' idea you suggested at the start of the thread.

    //
    Code:
    function stripParenths(s){
        var pat=/[)(]/g, rx=/\s*\([^)(]*\)\s*/;
        while(pat.test(s)){
            s= s.split(rx).join(' ');
        }
        return s.replace(pat,'');
    }
    //test
    Code:
    var str= 'Four score (and (seven (years)) ago) our fathers brought (forth unto) this continent';
    stripParenths(str)
    /* returned value: (String)
    Four score our fathers brought this continent
    */

    Last edited by mrhoo; 07-23-2010 at 08:34 PM.
    Reply With Quote
      #10  
    Old 07-25-2010, 06:37 AM
    Ayşe Ayşe is offline
    enjoiningOfConstancy++;
     
    Join Date: Sep 2007
    Location: Türkiye
    Posts: 160
    Code:
       
    <script type="text/javascript">
    
    var s='Four score (and seven (years) ago) our fathers brought (forth onto) this continent';
    
    var re = /(^[^)(]*(?=\())|(\)[^)(]*\()|(\)[^)(]*$)/g;
    
    var m = s.match(re).join("").replace(/[)(]/g,"");
    
    alert(m); // Four score our fathers brought this continent
    
    </script>
    __________________
    <div id="t" style="background-color: pink">The Time Through Ages. In the Name of Allah, Most Gracious, Most Merciful. 1. By the Time, 2. Verily Man is in loss, 3. Except such as have Faith, and do righteous deeds, and (join together) in the mutual enjoining of Truth, and of Patience and Constancy.</div>

    <script type="text/javascript">
    Math.PHI=(1+ Math.sqrt(5))/2;
    var r=Math.random()*161.8, h=161+r, el=document.getElementById("t").style;
    el.width=h*Math.PHI; el.height=h;
    </script>
    Reply With Quote
      #11  
    Old 07-30-2010, 03:26 PM
    Ayşe Ayşe is offline
    enjoiningOfConstancy++;
     
    Join Date: Sep 2007
    Location: Türkiye
    Posts: 160
    My codes I wrote was not very well. So I wrote a new code. I think this code is not limited.

    Code:
      
    <script type="text/javascript">
    
    var s='Four (two(score (and) seven (years) ago our) fathers) brought (forth onto) this continent';
    
    s = s.replace(/\([^)(]*\)/g,"").replace(/[^)(]*\)/g,")").replace(/\([^)(]*/g,"(").replace(/[)(]*/g,"");
    
    alert(s);  // Four brought this continent
    
    </script>
    __________________
    <div id="t" style="background-color: pink">The Time Through Ages. In the Name of Allah, Most Gracious, Most Merciful. 1. By the Time, 2. Verily Man is in loss, 3. Except such as have Faith, and do righteous deeds, and (join together) in the mutual enjoining of Truth, and of Patience and Constancy.</div>

    <script type="text/javascript">
    Math.PHI=(1+ Math.sqrt(5))/2;
    var r=Math.random()*161.8, h=161+r, el=document.getElementById("t").style;
    el.width=h*Math.PHI; el.height=h;
    </script>

    Last edited by Ayşe; 07-30-2010 at 03:56 PM.
    Reply With Quote
      #12  
    Old 07-31-2010, 06:11 AM
    Ayşe Ayşe is offline
    enjoiningOfConstancy++;
     
    Join Date: Sep 2007
    Location: Türkiye
    Posts: 160
    The codes I wrote without using loop did not give the desired result.

    In order to reach the desired result, loop must be used. The problem was resolved for me.
    __________________
    <div id="t" style="background-color: pink">The Time Through Ages. In the Name of Allah, Most Gracious, Most Merciful. 1. By the Time, 2. Verily Man is in loss, 3. Except such as have Faith, and do righteous deeds, and (join together) in the mutual enjoining of Truth, and of Patience and Constancy.</div>

    <script type="text/javascript">
    Math.PHI=(1+ Math.sqrt(5))/2;
    var r=Math.random()*161.8, h=161+r, el=document.getElementById("t").style;
    el.width=h*Math.PHI; el.height=h;
    </script>
    Reply With Quote
      #13  
    Old 07-31-2010, 01:08 PM
    Jona's Avatar
    Jona Jona is offline
    Registered User
     
    Join Date: Jan 2003
    Location: Texas
    Posts: 10,636
    I'm sure a RegExp can achieve literally anything. I only fiddled for a couple minutes, but this is a starting place, I believe. Of course, it assumes that you're always dealing with words and parentheses; I haven't tested it with a string other than the one shown below.

    One caveat: words that have trailing letters without a space or non-word character get truncated. For example, the string "o(rang)e" would turn into "o" instead of "oe." Adding a space so that it becomes "o(rang) e" produces the expected result, though.

    EDIT: Fixed the aforementioned caveat. The following RegExp should work. Let me know.

    Code:
    var s = 'Four score (and (seven (ye(a)rs)) ago) our fathers brought (forth unto) (this (is) (a (nother) )) continent (blah) ble(e) o(rang)e asdf asdf asdf asdf () asdf (hello) world (w)o((lds))a';
    
    var x = /(\([^\)]*\)[\)]*)*(?:\w*\))*/g;
    
    var r = s.replace(x,'');
    
    console.log(r);
    __________________
    Slightly Remarkable

    Last edited by Jona; 07-31-2010 at 01:13 PM.
    Reply With Quote
      #14  
    Old 08-01-2010, 04:25 AM
    Ayşe Ayşe is offline
    enjoiningOfConstancy++;
     
    Join Date: Sep 2007
    Location: Türkiye
    Posts: 160
    Jona,
    Thank you for your code.

    I tried your code. And It is working.
    Code:
    <script type="text/javascript">
    
    
    var s = 'Four score (and (seven (ye(a)rs)) ago) our fathers brought (forth unto) (this (is) (a (nother) )) continent (blah) ble(e) o(rang)e asdf asdf asdf asdf () asdf (hello) world (w)o((lds))a';
    
    var x = /(\([^\)]*\)[\)]*)*(?:\w*\))*/g;
    
    var r = s.replace(x,'');
    
    alert(r); // Four score our fathers brought  continent ble oe asdf asdf asdf asdf asdf world oa
    
    
    </script>
    I wrote a new code. It worked.
    Code:
    <script type="text/javascript">
    //  http://www.webdeveloper.com/forum/showthread.php?t=233252
    
    
    var s = 'Four(score one (and (seven eaea (ye(a) rs aaabcd)) vvvvv ago) our fathers) brought (forth unto) (this (is) (a (nother) )) continent (blah) ble(e) o(rang)e asdf asdf asdf asdf () asdf (hello) world (w)o((lds))a';
    
    var n =/([^(]*\))/g;
    
    var b = s.match(n);
    alert(b);
     
    var c = /\([^)]*/g;
    
    var d = s.match(c);
    
    alert(d);
    
    var f = /(\([^)]*)([^(]*\))/g;
    
    var h = s.match(f);
    
    alert(h);
    
    var s = s.replace(f,"");
    
    alert(s);  // Four brought continent ble oe asdf asdf asdf asdf asdf world oa
    
    </script>
    final code:
    Code:
    <script type="text/javascript">
    //  http://www.webdeveloper.com/forum/showthread.php?t=233252
    
    
    var s = 'Four(score one (and (seven eaea (ye(a) rs aaabcd)) vvvvv ago) our fathers) brought (forth unto) (this (is) (a (nother) )) continent (blah) ble(e) o(rang)e asdf asdf asdf asdf () asdf (hello) world (w)o((lds))a';
    
    var s = s.replace(/(\([^)]*)([^(]*\))/g,"");
    
    alert(s);  // Four brought continent ble oe asdf asdf asdf asdf asdf world oa
    
    </script>
    __________________
    <div id="t" style="background-color: pink">The Time Through Ages. In the Name of Allah, Most Gracious, Most Merciful. 1. By the Time, 2. Verily Man is in loss, 3. Except such as have Faith, and do righteous deeds, and (join together) in the mutual enjoining of Truth, and of Patience and Constancy.</div>

    <script type="text/javascript">
    Math.PHI=(1+ Math.sqrt(5))/2;
    var r=Math.random()*161.8, h=161+r, el=document.getElementById("t").style;
    el.width=h*Math.PHI; el.height=h;
    </script>

    Last edited by Ayşe; 08-01-2010 at 04:55 AM.
    Reply With Quote
      #15  
    Old 08-01-2010, 07:38 AM
    Kor's Avatar
    Kor Kor is offline
    Red Devil Moderator
     
    Join Date: Dec 2003
    Location: Bucharest, ROMANIA
    Posts: 12,658
    Thank you all for the various ideas. Thanks to a Forum we all can keep learning new approaches.
    Reply With Quote
    Reply

    Bookmarks


    Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
     
    Thread Tools
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is Off
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 04:52 PM.



    Acceptable Use Policy

    Internet.com
    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers

    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.