1

Given foo bar monkey [foo bar monkey] foo bar monkey, how would you match only the bar within the brackets?

\[(bar)+\] is as close as I can get it from an understanding and research perspective (brackets are matched, then we're selecting only the exact text within the brackets 1 or more times) however it matches nothing I want it to. \[(.*)+\] matches everything in brackets, including the brackets, but I can't seem to filter it to only bar regardless of what I try.

EDIT: I'm using a replace in directory function in a JetBrains IDE. I'm not sure what language they use for processing regex.

forrestmid
  • 1,494
  • 17
  • 25
  • 1
    What tool / lang you are using? – revo Feb 20 '18 at 16:52
  • Please indicate the language you are using. In any case, have you tried the regex `\[.*(bar).*\]` ? – Laurent H. Feb 20 '18 at 17:00
  • Try [`\[[^ ]+ (bar) [^]]+]`](https://regex101.com/r/OiGogq/1) – The fourth bird Feb 20 '18 at 17:09
  • @revo I'm doing a directory replace in a JetBrains IDE. I'm not sure what language they use for this. – forrestmid Feb 20 '18 at 17:09
  • Is unbalanced brackets existence probable? – revo Feb 20 '18 at 17:11
  • @Thefourthbird I don't that the IDE is not using perl for the regex. It think it's javascript. – forrestmid Feb 20 '18 at 17:12
  • @revo If you mean something along the lines of `[ foo bar [ foo bar ]]` or `[ foo bar ] [ foo bar ]`, then no. I'll be able to take care of those on a case by case basis. – forrestmid Feb 20 '18 at 17:14
  • Check this `bar(?=[^\]\[\\]*(?:\\.[^\]\[\\]*)*\])` – revo Feb 20 '18 at 17:16
  • And if you try [`\[[^ ]+ (bar) [^\]]+\]`](https://regex101.com/r/gVVt5e/1) with the escaped closing bracket? – The fourth bird Feb 20 '18 at 17:17
  • @revo That works, but I can't figure out how. Please post an answer so I can mark it so. I simplified my answer to post on stackoverflow and assumed, incorrectly, apparently, that I'd be able to change the answer to fit my situation. Check [here](https://regex101.com/r/gVVt5e/2) to see what I'm trying to do. – forrestmid Feb 20 '18 at 17:44
  • `\[[^\[\]]*(bar)[^\[\]]*\]` because capture groups are friendly. –  Feb 20 '18 at 17:44
  • This `text within the brackets 1 or more times)` is unclear. If you're saying you want to match all the bar's separately inside brackets like `[foo bar bar baz bar bar]` then a lookahead is needed. However, if not, these days, misinformed programmers think that they only want to match the subtext only as an _entire match_. This is utterly absurd, and why they make capture groups. If there is a scenario where you have more than one bar per paired bracket, it is wiser to capture the entire content's of the brackets, then run a global find on that. –  Feb 20 '18 at 18:01
  • I'm not sure if jetbrain uses Java regex flavor fully but if it does test this: `(?<=bar\([^(\\]{0,9999}(\\.[^(\\]{0,9999}){0,9999})chipmunk` it doesn't work in regex101.com though and please don't forget to ask for your real world issue next time you are going to post a question. – revo Feb 20 '18 at 18:01

5 Answers5

1

To match any bar within brackets (by knowing that unbalanced brackets are not likely to happen) you can use below regex:

bar(?=[^\]\[\\]*(?:\\.[^\]\[\\]*)*\])

RegEx breakdown:

bar     # Match `bar`
(?=     # Starting a positive lookahead, works as If condition
    [^\]\[\\]*  # If without matching `]` or `[` or `\`
    (?: # Start of non-capturing group #1
        \\.[^\]\[\\]* # Repeat last pattern in addition to matching escaped chars
    )*  # Many times, end of NCG #1
    \]  # When it ends to `]`
)       # End of lookahead

Running this over a string like this:

foo bar monkey [foo bar monkey bar foo] foo bar monkey [foo bar monkey bar foo]

will match all bars within brackets. You may want to enclose it with \b to ensure matching bar words only: \bbar\b.

Live demo

revo
  • 47,783
  • 14
  • 74
  • 117
0

JetBrains' IDEs are written in Java 1.4 (which includes Java 1.4's regex engine). There are multiple ways you can accomplish what you're trying to do, but likely the easiest method is to not use capturing groups. Java supports variable length lookbehinds so long as you don't use the + or * quantifiers. As a replacement for these unsupported quantifiers, you can use something like {0,1000} to replace * and {1,1000} to replace +.

(?<=\[[^]]{0,1000})bar
  • (?<=\[[^]]{0,1000}) Positive lookbehind ensuring what precedes matches the following
    • \[ Matches [ literally
    • [^]]{0,1000} Match any character except ] between 0 and 1000 times
  • bar Match this literally

Running this regex yields the following results for me (using PHPStorm as a test)

enter image description here

ctwheels
  • 21,901
  • 9
  • 42
  • 77
  • This doesn't work when `bar` is not the middle word or if there are any more than 1 word before `bar` or if there are no words after bar, etc. It just matches the second word inside of the brackets. – forrestmid Feb 20 '18 at 17:35
  • @forrestmid are you looking to always match `bar`? – ctwheels Feb 20 '18 at 17:36
  • Yes. Only bar, only while in brackets. – forrestmid Feb 20 '18 at 17:36
  • @forrestmid please see edits. I changed regex. This should work for you. One last question though, do you want to match `bar` if it's part of another word such as `bartender`? – ctwheels Feb 20 '18 at 17:41
0

You could possibly get along with

\[(?:(?!]).)*?bar

See a demo on regex101.com.


That is
\[         # match [
(?:        # non-capturing group
    (?!]). # neg. lookahead forbidding ]
)*?        # as few as possible
bar        # match bar

To capture bar, you could use

\[(?:(?!]).)*?(bar)

And use the first group.

Jan
  • 42,290
  • 8
  • 54
  • 79
-1

Try

.*\[[^]]*?(bar)[^[]*?\].*

Which should capture bar as long as it is inside of some brackets. The [^]]*? / [^[]*? on each side of the (bar) are needed to consume the other things that are inside the brackets with the bar.

Note that this will not properly handle nested brackets, and will only find one bar, along with probably many other restrictions.

lxop
  • 7,596
  • 3
  • 27
  • 42
-1

Check this out. It works fine.

\[\w*\s(bar)\s\w+\]

https://regex101.com/r/FylOMj/1

Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
Md. Miraj Khan
  • 377
  • 3
  • 15