1

Is there a Regular Expression I could use in the Find/Replace feature of my text editor (Jedit) to do the following:

Match any lines in a text file that meet these criteria:

  1. The line ends with a closing parenthesis
  2. An opening parenthesis exists somewhere on the same line

If it matches I need to wrap all of the text on the line - but not any whitespace at the start of the line- inside # signs.

Example 1

This line:

Total reimbursements (before end of Q1)

needs to be replaced with this:

#Total reimbursements (before end of Q1)#

Example 2 (leading whitespace)

This line (where there is whitespace before the word Total):

                             Total reimbursements (before end of Q1)

needs to be replaced with this (the # sign is placed before the first letter on the line):

                             #Total reimbursements (before end of Q1)#

but NOT with this:

#                             Total reimbursements (before end of Q1)#

Sample text file:

Base Expenses
&&&&&&&&&&&&&&&&&&&&&&&


Provides options towards multilateral improvements

Opening Debt(Option patterns)
          A copy provided externally

Customer Summary
&&&&&&&&&&&&&&&&&&&&&&&&&

 External Console(foreign debt)
          Provide execution amounts
 Internal Console(domestic debt)
          Release to appropriations committee

Explanations provided to external clients

 Neutralized Amounts()
          Forex portion
Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Bowe
  • 181
  • 2
  • 10

4 Answers4

2

I did this:

regex = /^(\s*)(.*)\((.*)\)$/

and printed $1#$2($3)# on a match.

Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
  • It had no effect on my text file. – Bowe Mar 02 '10 at 10:14
  • it needs global and multiline flags /^(\s*)(.*)\((.*)\)$/gm global -> get all the matches; multiline -> '^' represents start of line (not start of string) and '$' represents end of line (not end of string) – Biroka Mar 02 '10 at 10:22
  • @Biroka: multiline mode is usually the default in a text editor, and the global part is achieved by clicking on `Replace All` instead of `Replace`. @Bowe: did you remove slashes at the ends? – Alan Moore Mar 02 '10 at 11:58
  • @Alan Moore: No I didn't remove the slashes, you're right. It does work without them. Sorry, user30997, my bad. – Bowe Mar 02 '10 at 18:19
  • `($3)` reinserts the parentheses and whatever was inside them. – Alan Moore Mar 02 '10 at 22:42
2

Regex:

^([ \t]*)(.*\(.*\))$

Replacement:

$1#$2#

The trickiest thing is making sure no part of the regex can match newlines. That's why I used [ \t]* instead of \s* and .* instead of [^(]* or [^)]*.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
  • This is the only solution here that has worked flawlessly against all of my test files. Thanks a lot!! – Bowe Mar 02 '10 at 21:13
1

UPDATE:

Ok, [^(]+ in jEdit default regex flag, eaten \n too (I don't see any options to set multiline flag in jEdit search/replace UI),

So, here is new one, confirmed with your updated text

Search: ^(\s*)([^(\n]+\([^)\n]*\))\s*$
Replace: $1#$2

--- previous answer ---

Jedit,

Search : ^(\s*)([^(]+\([^)]+\))\s*$
Replace : $1#$2

--- previous previous Answer ---

Python, '^(\s*)([^(]+\([^)]+\))\s*$'

>>> import re
>>>
>>> re.sub('^(\s*)([^(]+\([^)]+\))\s*$','\\1#\\2','Total reimbursements (before end of Q1)')
'#Total reimbursements (before end of Q1)'
>>>
>>> re.sub('^(\s*)([^(]+\([^)]+\))\s*$','\\1#\\2','                             Total reimbursements (before end of Q1)')
'                             #Total reimbursements (before end of Q1)'
  • assuming there is only one bracket in the line
  • \s* in the end would not need, if there is trailing spaces
  • you would probably need re.MULTILINE flag too, if you want to process multiple lines in one shot.
YOU
  • 120,166
  • 34
  • 186
  • 219
  • Tried it on one sample where there is no text between the parentheses and it had no effect there. On a different sample where there is text between the parentheses, it puts the pound sign earlier in the file rather than on the same line where the match ocurred. – Bowe Mar 02 '10 at 10:34
  • Thanks for the screenshot. Those are the settings I'm using also. It just doesn't seem to work on my test files. – Bowe Mar 02 '10 at 10:58
  • Could you provide more test patterns in the question? – YOU Mar 02 '10 at 11:05
  • Thanks for persevering. I added some new test cases above. – Bowe Mar 02 '10 at 11:20
  • Yes! It works! The only change that's needed to your "Replace" pattern is the trailing pound sign which you forgot. So, with this replace pattern it works perfectly: $1#$2# Thanks! – Bowe Mar 02 '10 at 18:09
  • Upon further testing, this didn't work as well as Alan Moore's solution. – Bowe Mar 02 '10 at 21:13
0

Try the following:

^\s*(?=((.*)(?<=\((.*)\))$))|(?<=\((.*)\))$

It looks ahead and behind to match lines with a closing bracket at the end of the line only if preceded by an opening bracket.

Replacing with a hash will give you the desired output, it will strip the whitespace at the start of the line also, not suer if this is your desired goal but seems most likely.

Justin Wignall
  • 3,490
  • 20
  • 23
  • I got this error when I ran it in Jedit: java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 23 – Bowe Mar 02 '10 at 11:01
  • Yes, that's an invalid regex in Java, as it is in most other regex flavors. It works in EditPadPro, but as you said, it strips leading leading whitespace--including blank lines. – Alan Moore Mar 02 '10 at 12:13