2

I have below resultant php.ini file, after I was able to remove the comments & spaces thro' some simple Regex find/replace steps:

[PHP]
engine = On
short_open_tag = Off
....
....
[CLI Server]
cli_server.color = On
[Date]
[filter]
[iconv]
[imap]
[intl]
[sqlite3]
[Pcre]
[Pdo]
[Pdo_mysql]
pdo_mysql.default_socket=
[Phar]
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[ODBC]
....
....
[dba]
[opcache]
[curl]
curl.cainfo = "{PHP_Dir_Path}\extras\curl\cacert.pem"
[openssl]
[ffi]

As you can see, there are multiple occurrences where multiple empty sections(sections which doesn't contain any semicolon-less(non-commented) lines) in this file, and I can't bring myself to make a regex find/replace pattern that could let me remove all such empty sections in one go, so that it becomes like below:

[PHP]
engine = On
short_open_tag = Off
....
....
[CLI Server]
cli_server.color = On
[Pdo_mysql]
pdo_mysql.default_socket=
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[ODBC]
....
....
[curl]
curl.cainfo = "{PHP_Dir_Path}\extras\curl\cacert.pem"

Can anyone help me out achieve, what I need ?

Vicky Dev
  • 1,893
  • 2
  • 27
  • 62
  • 1
    Maybe something like this will suffice: [`^\[.*+\n(?=\s*\[)`](https://regex101.com/r/xvoRlo/1) – bobble bubble Jul 14 '22 at 20:58
  • 1
    I saw it fails for the last element `[ffi]` - maybe better: [`^\[.*+\n?(?!\s*[^\[])`](https://regex101.com/r/1BUh4C/1) (can't answer atm, busy) – bobble bubble Jul 14 '22 at 21:11
  • 1
    That does the job perfect, thanks a lot, and you can take your time, in converting this to an answer, maybe tomorrow or day-after, whenever, thanks again !! – Vicky Dev Jul 14 '22 at 21:15

3 Answers3

1

You can try to match if there is a ] followed by a new line and then a [, with the following regex:

\]\n\[

EDIT:

As pointed by your comment, that would just get the ][ characters, so you could try this instead:

(\[(\w)+\]\n)(?!\w)

This will match a title that is not followed by a word in the next line.

EDIT2:

My previous answer would not get the last section if it was empty, so I changed it to check the newline OR end of file.

(\[(\w)+\])(\n(?!\w)|$)
hug
  • 36
  • 4
  • But this will keep the section title intact, as I mentioned I want to remove the entire empty section, incl. section title(and brackets), all such sections. – Vicky Dev Jul 14 '22 at 20:51
  • That's right, my bad! You can select only the titles of empty sections with this, which will look for titles that are not followed by a word: (\[(\w)+\]\n)(?!\w) (I will edit the answer) – hug Jul 14 '22 at 21:03
  • Yes your second suggestion seems to do the job well, thanks – Vicky Dev Jul 14 '22 at 21:07
1

You need to tell your regex-engine to use the single-line aka "dotall" mode. Then you can easily pick out any bracketed strings that are only separated by a newline:

 /\[[^\]]+\]\s\[[^\]]+\]/gs

The s flag enables "dotall" mode.

Update: Overlooked one obvious problem with my solution. It gets a bit more complicated now, using a lookahead (?:\s(?=\[)). Also extra caution needs to be taken to capture the last empty section, which is done with the |$ part. Regexr link updated...

 /\[[^\]]+\](?:\s(?=\[)|$)/gs
zb226
  • 9,586
  • 6
  • 49
  • 79
  • Thanks for nice answer, but bad luck, the Text editors I am using are either Sublime Text or Notepad++ and I don't know how to enable such feature in those editors' settings, any workaround that could work just like your above answer and provide the needed result ? – Vicky Dev Jul 14 '22 at 20:56
  • Oops, one more thing I forgot to add, if you see in the results in your regexr link, your regex is also removing the section headers that actually contain non-commented lines, like `[mail function]`, and that section has lines such as `SMTP = localhost smtp_port = 25 mail.add_x_header = Off`. So can you please improve your answer so it doesn't remove those non-empty section headers ? – Vicky Dev Jul 14 '22 at 21:00
  • @VickyDev Did that even though it won't be any help with the most recent npp, I checked it. Couldn't check sublime though. Please state your regex environment beforehand next time. – zb226 Jul 14 '22 at 21:11
  • 1
    Sure will take care of mentioning this upfront now onwards, thanks !! – Vicky Dev Jul 14 '22 at 21:17
1

An idea to look ahead after lines starting with [ for another opening bracket (or end).

^\[.*+\s*+(?![^\[])

Here is the demo at regex101 - If using NP++ uncheck: [ ] . dot matches newline

In short words it matches lines starting with [ up to eol and any amount of whitespace...
if there is either no character ahead or the next character is another [ opening bracket.
Side note: Its positive equivalent is ^\[.*+\s*+(?=\[|\z) where \z matches end of string.

bobble bubble
  • 16,888
  • 3
  • 27
  • 46