0

I need to check wether matching parenthesis is present in a string that might have emoticons (like :) or :(). For example, "(:)())()", "(abcd)()ghijk)((mnop)qert)"

I have used the patterns "^[:\\(|:\\)]" to check for emoticons and "\\([^()]*\\)" to check for matching parenthesis present, but they are not detected. How can I do this?

jscs
  • 63,694
  • 13
  • 151
  • 195
user2071152
  • 1,161
  • 1
  • 11
  • 25
  • [Can regular expressions be used to match nested patterns?](https://stackoverflow.com/q/133601) – jscs Jul 30 '17 at 13:03
  • @JoshCaswell - To be fair to the OP your dupe isn't one really as the OP wishes to handle sequences (the emoji) which change the meaning of the delimiters. – CRD Jul 30 '17 at 22:01
  • Oh, I completely missed that part of the question, @CRD. Apologies. Reopened. – jscs Jul 31 '17 at 11:55
  • Related/helpful: [Checking NSString for balanced delimiters](https://stackoverflow.com/q/20304963) – jscs Jul 31 '17 at 11:55
  • @user2071152: These are [emoticons](https://en.wikipedia.org/wiki/Emoticon), not [emoji](https://en.wikipedia.org/wiki/Emoji). – jscs Jul 31 '17 at 11:59

2 Answers2

1

The really simple solution to this problem is to count the parentheses, trying to solve it with regular expressions is hard though extended regular expressions can handle it. Here is a sketch of the simple algorithm:

  1. Set openParenthesisCount to 0
  2. Iterate over the string:
    1. If current character is ( increment openParenthesisCount
    2. If current character is ) decrement openParenthesisCount, if count goes negative then fail (too many closing)
    3. If current character is : lookahead and skip next character if it is a parenthesis (skip smilies)
  3. If openParenthesisCount is zero => succeed

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • Will the approach of regular expression be faster as compared to this approach? – user2071152 Aug 02 '17 at 20:46
  • Unless you are dealing with very large strings that is probably the wrong question to ask. This algorithm is simple to implement and understand, and I don't know that you have a RE that solves it yet (the current other answer does not as it understood your question differently), so that makes the choice rather easy surely? Write your code, if there is a problem profile, if that finds a perf issue, optimise. – CRD Aug 02 '17 at 21:16
0

As far as I can tell, you want to match a string if and only if it contains matching parentheses, after ignoring every occurrence of ":)" and ":(" in the string, if any.

So, try this:

^((?!:).)*\(.*(?<!:)\).*



It will match the following strings:

  • ()
  • (abd)
  • (())(
  • (:))
  • (:(:))
  • (:)())()
  • (abcd)()ghijk)((mnop)qert)
  • (abc):
  • (:abc)

But will NOT match the following:

  • )(
  • (:)
  • (:(
  • :(:)
  • :()
  • (:)
  • :()(:)
  • (
  • )
  • (abc
  • abc)
  • (abc:)
  • :(abc)
AppyFizz
  • 14
  • 4
  • I think it might match `((()(:)))a(`... This isn't really your problem, regular expressions are not the way to tackle this though extended regular expressions can handle it. – CRD Jul 30 '17 at 06:23
  • @CRD It should match the given expression though, since in `((()(:)))a(` , the inner parens "()" do form a valid pair of parantheses. While, in the example above, the whole string itself does not have valid parens, I believe @user2071152 wants to match all strings containing a valid pair of parens as a substring? – AppyFizz Jul 30 '17 at 07:08
  • Your pattern matches the whole string, including the unbalanced parenthesis. As to what the OP is precisely asking, you might be right. The usual problem is to find strings which only contain balanced parentheses, if you are right and only a single pair of balanced parentheses is what is after the solution becomes trivial. – CRD Jul 30 '17 at 08:29
  • Yeah, it is kind of trivial It's just the ":)" and the ":(" making it a tad harder than usual – AppyFizz Jul 30 '17 at 08:44
  • @AppyFizz yes i want to match all valid parenthesis in the string for e.g., (()) is a valid pattern but ((()) is invalid and (())) is also invalid. (:)) is a valid string. ((:()) is also a valid string. – user2071152 Jul 31 '17 at 04:16