How to match groups of strings that do not contain some substring




I need to match groups of strings that have as boundaries the sequence "\_\_" char (two underscores)


 eg:



```
hello \_\_1the\_re\_\_ my name is \_\_pe er33\_\_

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
```

 "1the\_re" and "pe er33" must be matched


my problem is defining "a string that does not contain a character sequence" 



```
/\_\_((?!\_\_).*)\_\_/

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
```

I tried this but it doesn't work ...


Thank you!
Are you close:



```
/\_\_((?!\_\_).)*\_\_/

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
```

works. The star must be outside the repeating group, so the scan is performed at each position, not immediately after the presenter `__`
  




 (adsbygoogle = window.adsbygoogle || []).push({});
 
  

.



  




 (adsbygoogle = window.adsbygoogle || []).push({});
 
  

Since this does not display the correct text (I am assuming you want the content between the double underscores to be captured), you probably want



```
/\_\_((?:(?!\_\_).)*)\_\_/

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
```
The existing solutions based on `findall` are fine for non-overlapping matches (and no doubt optimal except maybe for HUGE number of matches), although alternatives such as `sum(1 for m in re.finditer(thepattern, thestring))` (to avoid ever materializing the list when all you care about is the count) are also quite possible. Somewhat idiosyncratic would be using `subn` and ignoring the resulting string...:



```
def countnonoverlappingrematches(pattern, thestring):
  return re.subn(pattern, '', thestring)[1]

```

the only real advantage of this latter idea would come if you only cared to count (say) up to 100 matches; then, `re.subn(pattern, '', thestring, 100)[1]` might be practical (returning 100 whether there are 100 matches, or 1000, or even larger numbers).


Counting **overlapping** matches requires you to write more code, because the built-in functions in question are all focused on NON-overlapping matches. There's also a problem of definition, e.g, with pattern being `'a+'` and thestring being `'aa'`, would you consider this to be just one match, or three (the first `a`, the second one, both of them), or...?


Assuming for example that you want possibly-overlapping matches *starting at distinct spots in the string* (which then would give TWO matches for the example in the previous paragraph):



```
def countoverlappingdistinct(pattern, thestring):
  total = 0
  start = 0
  there = re.compile(pattern)
  while True:
    mo = there.search(thestring, start)
    if mo is None: return total
    total += 1
    start = 1 + mo.start()

```

Note that you do have to compile the pattern into a RE object in this case: function `re.search` does not accept a `start` argument (starting position for the search) the way *method* `search` does, so you'd have to be slicing thestring as you go -- definitely more effort than just having the next search start at the next possible distinct starting point, which is what I'm doing in this function. All whitespace: `/\s/g`  

All non-alphanumerics: `/[^a-zA-Z0-9]/g` [@cssc](/u/cssc), another option would be to take the regex way.

first, it finds the index of the 5th pipe.

then, it takes the substring until that index.

give this a try:

inputstr.substring(0, regex.matches(inputstr, "\|")(4).index + 1) How you do this will depend on a number of factors: since you haven't tried to explain in any detail, I'll assume you know nothing, and just give you the basics.  

  

The easiest way to do this is to read the text file into a single string, and then use the .NET framework to find the match:  


```
Dim text As String = File.ReadAllText("D:\Temp\MyFile.txt")
Dim index As Integer = text.IndexOf("hello")
If index >= 0 Then
   ' String is in file, starting at character "index"
End If
```
  

There are other ways, but that is pretty much the simplest. Your test is redundant, since you are already querying only for matching records. In this case, you will get no rows if there is no match, therefore you will never hit the else clause in the loop.  

  

Instead, it is enough to check if there are any matching records at all. The example below shows how (note that you can put a condition straight into Any() instead of specifying Where()).  

  

C#Copy Code

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace CustomerMaster
{
    public partial class CustomerMaster : System.Web.UI.Page
    {
 
        private void AddData()
        {
            
            OperationsDataContext AddDb = new OperationsDataContext();
            CustomerMast cm = new CustomerMast();
            
                        
            cm.CustomerCode = txtCustCde.Text;
            cm.CustomerName = txtCustName.Text;
            cm.CustomerAddress = txtCustAdd.Text;
            cm.BrkrCode = txtBrkCode.Text;
            cm.BrokerName = txtBrkName.Text.
            cm.CrrCode = txtCrrCode.CarrierCode;
            cm.CarrierName =  txtCrrName.Text;
            cm.StnCode=sm.StationCode;
            cm.StationName = txtStnName.Text;
            cm.VatNo=txtVatNo.Text;
            cm.TinNo=txtTinNo.Text;
            cm.TMCO=txtTMCONo.Text;
            cm.PanNo = txtPAN.Text;
			
	    if(AddDb.CustomerMasts.Any(c=>c.CustomerCode == txtCustCde.Text))
            {
	        Response.Write("Error! CustomerCode Exits");
	    }
	    else
	    {
                AddDb.BrokerMasts.InsertOnSubmit(bm);
                AddDb.CarrierMasts.InsertOnSubmit(crm);
                AddDb.StationMasts.InsertOnSubmit(sm);
                AddDb.CustomerMasts.InsertOnSubmit(cm);

	        AddDb.SubmitChanges();
            }         
        }
 
        protected void btnAdd\_Click(object sender, EventArgs e)
        {
            AddData();
        }
    }
}
``` JavaScript *itself* has nothing built in for handling query string parameters. 


Code running in a (modern) browser you can use the [`URL` object](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) (which is part of the APIs provided by browsers to JS):





```
var url_string = "http://www.example.com/t.html?a=1&b=3&c=m2-m3-m4-m5"; //window.location.href
var url = new URL(url_string);
var c = url.searchParams.get("c");
console.log(c);
```









For older browsers (including Internet Explorer), you can use [this polyfill](https://github.com/ungap/url-search-params) or the code from the original version of this answer that predates `URL`:


You could access `location.search`, which would give you from the `?` character on to the end of the URL or the start of the fragment identifier (#foo), whichever comes first.


Then you can parse it with this:





```
function parse_query_string(query) {
  var vars = query.split("&");
  var query_string = {};
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    var key = decodeURIComponent(pair[0]);
    var value = decodeURIComponent(pair[1]);
    // If first entry with this name
    if (typeof query_string[key]  "undefined") {
      query_string[key] = decodeURIComponent(value);
      // If second entry with this name
    } else if (typeof query_string[key]  "string") {
      var arr = [query_string[key], decodeURIComponent(value)];
      query_string[key] = arr;
      // If third or later entry with this name
    } else {
      query_string[key].push(decodeURIComponent(value));
    }
  }
  return query_string;
}

var query_string = "a=1&b=3&c=m2-m3-m4-m5";
var parsed_qs = parse_query_string(query_string);
console.log(parsed_qs.c);
```




You can get the query string from the URL of the current page with:



```
var query = window.location.search.substring(1);
var qs = parse_query_string(query);

``` here is a list of the symbols by their names: ampersand & apostrophe or single quote ' asterisk * at @ back quote ` back slash \ braces or curly braces {} brackets [] carat ^ close brace } close bracket ] close parenthesis ) colon : comma , dollar $ equal = exclamation point ! greater than > less than < minus or hyphen - open brace { open bracket [ open parenthesis ( parenthesis () percent % pipe or bar | plus + octothorpe # quote " semi-colon ; slash or forward slash / tilde ~ underscore \_ hi [@nathan\_lively](/u/nathan_lively) - i’m not as familiar with the limitations of the bubble api, but i think i see two problems that might be causing the error.

the list you’re sending should look like this: ["1:1 matched reference"]. each array value needs to be wrapped in quotes.

you probably also don’t need quo… Okay well if those query parameters really do represent arbitrary text a visitor enters into fields, then personally I would push them to separate Adobe Analytics variables instead of concatenate them, because there's no guarantee on how many characters they will be or what characters will be entered. 

I'm not sure I understand what you mean... is your site just using different query parameters for search terms, depending on the page or search widget used? So e.g. maybe you do a search and it pops k=[search term] but on search results page you do another search and it instead pops query=[new search term] ?  If so, then it sounds to me like you shouldn't concat them, but instead just look for either one and push to the variable.  

Or is it that a visitor can go to your site and search for something that results in both of those parameters showing up in the URL at the same time, with different values? 

I think I need clarification about how your site actually works vs. these two parameters. 




[View solution in original post](/t5/dynamic-tag-management-questions/internal-search-term-tracking/m-p/278167#M1141) grammer lesson! "their" not there. find an internet phone book.