You could use the Rules block visibility module for this. Here is a quote from its project page:
The Rules block visibility module allows Rules components to be used to control block visibility. This provides Drupal administrators and developers extreme flexibility in controlling when blocks should be displayed on their websites, in addition to the default visibility options provided by Drupal.
The general idea is that if you can do it with Rules, you can use it to control block visibility, so the possibilities are limitless.
Need to show a block only for users registered more than a month ago?
Perhaps you have a block that must be shown only between 8am-5pm on weekdays?
What about displaying or hiding a block based on current weather conditions?
All of this can be done by using Rules block visibility.
With that, and as per the "if you can do it with Rules, you can use it to control block visibility" above, you've reduced your question to making Rules "check the path of the current page". So that the block is only shown on the pages with the (first 3) paths you mentioned, and not on the (last 3) paths were you want to hide that block.
For an illustration of how to use this module, refer to my answer to "How to stop a Views block from displaying to admins, such as user/1?". It includes a Rules Component (in Rules export format), which you should replace by this variation of it to make it match your specific question):
{ "rules_block_visibility_show_on_selected_paths" : {
"LABEL" : "Show block on selected paths",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"USES VARIABLES" : {
"module" : { "label" : "Module", "type" : "text" },
"delta" : { "label" : "Delta", "type" : "text" },
"result" : { "label" : "Result", "type" : "boolean", "parameter" : false }
},
"IF" : [
{ "AND" : [
{ "OR" : [
{ "text_matches" : {
"text" : [ "site:current-page:path" ],
"match" : "\/chapters\/university-of-florida\/classrooms\/class",
"operation" : "starts"
}
},
{ "text_matches" : {
"text" : [ "site:current-page:path" ],
"match" : "\/chapters\/university-of-chicago\/classrooms\/class",
"operation" : "starts"
}
},
{ "text_matches" : {
"text" : [ "site:current-page:path" ],
"match" : "\/chapters\/ucla\/classrooms\/cla",
"operation" : "starts"
}
}
]
},
{ "OR" : [
{ "NOT data_is" : {
"data" : [ "site:current-page:path" ],
"value" : "\/chapters\/university-of-florida\/"
}
},
{ "NOT data_is" : {
"data" : [ "site:current-page:path" ],
"value" : "\/chapters\/university-of-chicago\/"
}
},
{ "NOT data_is" : { "data" : [ "site:current-page:path" ], "value" : "\/chapters\/ucla\/" } }
]
}
]
}
],
"DO" : [ { "data_set" : { "data" : [ "result" ], "value" : "1" } } ],
"PROVIDES VARIABLES" : [ "result" ]
}
}
This Rules Component will make the block visible on any pages with a path that matches any of the first 3 paths you mentioned, provided such page does not have a path that also fits any of the last 3 paths you mentioned.
You could further enhance the above Rules Component (to make it more generic), by just replacing the Rules Conditions in it with something using an appropriate regular expression (related to the current path also). That would also help to reduce the need "to manually specify the paths whenever new chapters and classrooms are added" (as in your question).
Remark: the previous answer is incorrect ... the block would for sure not show on "chicago
" or "ucla
" related paths that also contain "classrooms
".