Splunk Search

How to get position of a not constant char/substring in another string?

Nikita_Danilov
Path Finder

Hi all!

As I understand, Splunk doesn't have any special functions for normal work with string.
I need to get index of a not constant char/substring in another string.
Substring is not constant, it's value from another field.

Solution for constant substring: http://answers.splunk.com/answers/66496/how-to-get-index-of-a-particular-letter-in-string

But, it has not work for dynamic substring. I tried to form regular expression:

index="b2b_integration_oss"
| eval string="Some long string"
| eval regExString=".*(?<substring>\b" + searchField + "\b).*"
| rex field=string regExString

Then, I got next error:

Error in 'rex' command: The regex 'regExString' does not extract anything. It should specify at least one named group. Format: (?<name>...).

Why doesn't exist in Splunk any analogs for SQL CHARINDEX function?

Anyone can guide me please on this?

Thanks!

0 Karma
1 Solution

martin_mueller
SplunkTrust
SplunkTrust

Something like this?

| stats count | eval haystack = "some long string" | eval needle = "some long string foo" | makemv needle | mvexpand needle
| eval replaced = replace(haystack, "(.*?)".needle.".*", "\1") | eval position = if(match(haystack, needle), length(replaced), -1)

That'll yield this result:

haystack           needle   position   replaced
some long string   some            0    
some long string   long            5   some
some long string   string         10   some long
some long string   foo            -1   some long string 

You'll get position=-1 if the needle is not contained in the haystack, and its first position if it is. Remove the non-greedy question mark from the regex to get the last position. Note, you may get unexpected results if the needle contains special regex characters.

For performance optimization you should move the replace into the then-branch of the if to avoid unnecessary regex'ing in case of non-matches - I've left it there for easy understanding of the steps involved.

View solution in original post

martin_mueller
SplunkTrust
SplunkTrust

Something like this?

| stats count | eval haystack = "some long string" | eval needle = "some long string foo" | makemv needle | mvexpand needle
| eval replaced = replace(haystack, "(.*?)".needle.".*", "\1") | eval position = if(match(haystack, needle), length(replaced), -1)

That'll yield this result:

haystack           needle   position   replaced
some long string   some            0    
some long string   long            5   some
some long string   string         10   some long
some long string   foo            -1   some long string 

You'll get position=-1 if the needle is not contained in the haystack, and its first position if it is. Remove the non-greedy question mark from the regex to get the last position. Note, you may get unexpected results if the needle contains special regex characters.

For performance optimization you should move the replace into the then-branch of the if to avoid unnecessary regex'ing in case of non-matches - I've left it there for easy understanding of the steps involved.

martin_mueller
SplunkTrust
SplunkTrust

Beats me... feel free to submit a feature request through a support ticket to get any function added you might need.

Nikita_Danilov
Path Finder

Martin, if there are functions "len" and "substring", why not add another one function for strings as "indexof".

0 Karma

martin_mueller
SplunkTrust
SplunkTrust

Well, there's pros and cons for having a built-in function for every single use case imaginable. In my mind it clutters the search language tremendously, and doesn't add to the power of the language.

0 Karma

Nikita_Danilov
Path Finder

Martin, it works fine for me:

| eval replaced = replace(haystack, "(.*?)".needle.".*", "\1")
| eval position = if(match(haystack, needle), length(replaced), -1)

Thanks!
Strange to me that there is no special built-in functions.

0 Karma

timpacl
Path Finder

There is a combination of built-in functions that can do this in one step. See my answer below.

0 Karma

timpacl
Path Finder

len(mvindex(split(lower([string]),"[char]"),0)). I have submitted an explanatory post below but it still hasn't shown up so here is the formula.

0 Karma

yannK
Splunk Employee
Splunk Employee

Can you attach an example of the event, and the expected result ?

0 Karma

yannK
Splunk Employee
Splunk Employee

It is possible to pass argument between a form input and a search string in a form dashboard.
You may try this approach. the variable will look like $searchField$

see http://docs.splunk.com/Documentation/Splunk/6.0.3/Viz/Buildandeditforms#Basic_form_example

Remark, your regex is not valid, you have non escaped double quotes in it..

Nikita_Danilov
Path Finder

yannK, thanks, but I need it in basic search, not only in Forms. I've used Martin's solution.

0 Karma
Get Updates on the Splunk Community!

Index This | I am a number, but when you add ‘G’ to me, I go away. What number am I?

March 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...