|
|||||||
| JavaScript JavaScript (not Java) Discussion and technical support, including AJAX and frameworks (JQuery, MooTools, Prototype...) |
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
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'; Code:
var finalstr='Four score our fathers brought this continent'; Code:
/\(.*?\)/g Code:
str=str.replace(/\(.*?\)/g,''); '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. |
|
#2
|
||||
|
||||
|
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>
|
|
#3
|
|||
|
|||
|
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,""); 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,"");
}
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 --;
}
}
__________________
Quote:
|
|
#4
|
||||
|
||||
|
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
|
|
#5
|
|||
|
|||
|
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:
|
|
#6
|
|||
|
|||
|
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> |
|
#7
|
||||
|
||||
|
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
__________________
libs: mini (updated) ASPmini myIO (new) dnd tmpl8 apps: snippets blog photos crypto image editor crapplets: json browse json view compressor time grads |
|
#8
|
|||
|
|||
|
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:
|
|
#9
|
|||
|
|||
|
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,'');
}
Code:
var str= 'Four score (and (seven (years)) ago) our fathers brought (forth unto) this continent'; stripParenths(str) Four score our fathers brought this continent */ Last edited by mrhoo; 07-23-2010 at 08:34 PM. |
|
#10
|
|||
|
|||
|
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> |
|
#11
|
|||
|
|||
|
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. |
|
#12
|
|||
|
|||
|
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> |
|
#13
|
||||
|
||||
|
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. |
|
#14
|
|||
|
|||
|
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> 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> 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. |
|
#15
|
||||
|
||||
|
Thank you all for the various ideas. Thanks to a Forum we all can keep learning new approaches.
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|