2

im looking for the regexp that make able to do this tasks

message Body Input: Test1 (Test2) (test3) (ti,ab(text(text here(possible text)text(possible text(more text))))) end (text)

the result that i want Result: (text(text here(possible text)text(possible text(more text))))

I want to collect everything that is inside ti,ab(................)

var messageBody = message.getPlainBody()
var ssFile = DriveApp.getFileById(id);
DriveApp.getFolderById(folder.getId()).addFile(ssFile);
var ss = SpreadsheetApp.open(ssFile);
var sheet = ss.getSheets()[0];
sheet.insertColumnAfter(sheet.getLastColumn());
SpreadsheetApp.flush();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn() + 1)                            
var values = range.getValues();

values[0][sheet.getLastColumn()] = "Search Strategy";

 for (var i = 1; i < values.length; i++) {                          
                             //here my Regexp 
                            var y = messageBody.match(/\((ti,ab.*)\)/ig);
                            if (y);        
                            values[i][values[i].length - 1] = y.toString(); 


                            range.setValues(values);
Moka
  • 93
  • 8
  • JavaScript does not allow you to use regex in such a way. To match the parentheses, you need recursive or balanced expressions, which JavaScript does not support. – O.O.Balance Mar 23 '18 at 09:48
  • This probably not a thing to do using regular expressions in JavaScript, as there is no decent way of matching the brackets. You may be better matching the start of the group then stepping though the rest of the string to count the brackets. – scagood Mar 23 '18 at 09:48
  • how can i solve that im quit new with javascript for this kind of tasks – Moka Mar 23 '18 at 09:49
  • Are you sure the string is like this? Because the number of `(` and `)` is not balanced here. Isn't one `)` missing before `end`? – Wiktor Stribiżew Mar 23 '18 at 10:20
  • @WiktorStribiżew thanks for your review i corrected ( now they are balanced – Moka Mar 23 '18 at 10:25

1 Answers1

2

The only solution you may use here is to extract all substrings inside parentheses and then filter them to get all those that start with ti,ab:

var a = [], r = [], result;
var txt = "Test1  (Test2) (test3) (ti,ab(text(text here(possible text)text(possible text(more text))))) end (text)";
for(var i=0; i < txt.length; i++){
    if(txt.charAt(i) == '(') {
        a.push(i);
    }
    if(txt.charAt(i) == ')') {
        r.push(txt.substring(a.pop()+1,i));
    }
}
result = r.filter(function(x) { return /^ti,ab\(/.test(x); })
          .map(function(y) {return y.substring(6,y.length-1);})
console.log(result);

The nested parentheses function is borrowed from Nested parentheses get string one by one. The /^ti,ab\(/ regex matches ti,ab( at the start of the string.

The above solution allows extracting nested parentheses inside nested parentheses. If you do not need it, use

var txt = "Test1 (Test2) ((ti,ab(text(text here))) AND ab(test3) Near Ti(test4) NOT ti,ab,su(test5) NOT su(Test6))";
var start=0, r = [], level=0;
for (var j = 0; j < txt.length; j++) {
  if (txt.charAt(j) == '(') {
    if (level === 0) start=j;
    ++level;
  }
  if (txt.charAt(j) == ')') {
     
    if (level > 0) {
      --level;
    }
    if (level === 0) {
     r.push(txt.substring(start, j+1));
    }
  }
}
console.log("r: ", r);
var rx = "\\b(?:ti|ab|su)(?:,(ti|ab|su))*\\(";
var result = r.filter(function(y) { return new RegExp(rx, "i").test(y); })
 .map(function(x) {
   return x.replace(new RegExp(rx, "ig"), '(') 
  });
console.log("Result:",result);

The pattern used to filter and remove the unnecessary words

\b(?:ti|ab|su)(?:,(ti|ab|su))*\(

Details

  • \b - a word boundary
  • (?:ti|ab|su) - 1 of the alternatives,
  • (?:,(ti|ab|su))* - 0 or more repetitions of , followed with 1 of the 3 alternatives
  • \( - a (.

The match is replaced with ( to restore it in the match.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • is that possible to get just `(text(text here(possible text)text(possible text(more text))))` as Result with `ti,ab` – Moka Mar 23 '18 at 10:58
  • 1
    @Moka See edit. `.map` will remove all `ti,ab(` and the last `)` from all the matches found. – Wiktor Stribiżew Mar 23 '18 at 11:02
  • can i add another condition with the same concept if i have just `ab(................)` or `ti(...............)` – Moka Mar 23 '18 at 15:30
  • 2
    @Moka If you need those substrings that start with `ab(` or `ti(` replace `/^ti,ab\(/.test(x)` with `/^(?:ti|ab)\(/.test(x)` – Wiktor Stribiżew Mar 23 '18 at 21:23
  • 1
    @I'-'I It won't work because the `end` is a placeholder. – Wiktor Stribiżew Mar 23 '18 at 21:23
  • @WiktorStribiżew Thanks! do you have idea how can i collect the Text with same concept Input Body `Ti,ab(.......)` start and end without parentheses and my output is just what inside the `Ti.ab` ----->(......) – Moka Mar 26 '18 at 11:54
  • @Moka Sorry, no idea what you mean. Please post some snippet link to better visualize the problem. – Wiktor Stribiżew Mar 26 '18 at 11:57
  • @WiktorStribiżew mean what i need to change in the code if i have this input `(test1) ti,ab(text(text here(possible text)text(possible text(more text))))` – Moka Mar 26 '18 at 12:01
  • @WiktorStribiżew could you help me to find a solution for this problem: https://stackoverflow.com/questions/49513195/extract-specifc-text-from-string-list – Moka Mar 27 '18 at 13:09
  • why u didn't add the `g` here `RegExp(rx, "i").test(y)` – MokiNex Mar 28 '18 at 09:08
  • 1
    @MokiNex See [Why does a RegExp with global flag give wrong results?](https://stackoverflow.com/questions/1520800/why-does-a-regexp-with-global-flag-give-wrong-results). – Wiktor Stribiżew Mar 28 '18 at 09:31
  • @WiktorStribiżew https://jsfiddle.net/rppzgu1f/14/ could you change the script to display just the string text of `(ti|ab|su|,)` – MokiNex Mar 28 '18 at 10:42
  • @MokiNex I do not understand what exact strings you need to display. `['ti, 'ab', 'su', ',']`? – Wiktor Stribiżew Mar 28 '18 at 10:48
  • Input= `((ti,ab(text(text here))) AND ab(test3) Near Ti(test4) NO dont need this words and ti,ab,su(test5) NOT su(Test6))` Ouput=`(((text(text here))) AND (test3) Near (test4) and (test5) NOT (Test6))` – MokiNex Mar 28 '18 at 11:33
  • @MokiNex Sorry, I can't get the requirements. You say * just the string text of `(ti|ab|su|,)`*, but your expected output contains other texts, like `NOT`, etc. – Wiktor Stribiżew Mar 28 '18 at 13:23