VHDL: Can a signal be used as an index for an aggregate?
You're conflating legal syntax and semantics. 

Your aggregate uses element association.  

What element of reg_clk_en has the name write_reg?  

See IEEE Std 1076-2008 9.3.3 Aggregates, note choices simple_expression and element_simple_name in the BNF, paragraph:

element_association ::=  
    [ choices =&gt; ] expression  

choices ::= choice { | choice }  

choice ::= 
      simple_expression
    | discrete_range
    | element_simple_name
    | others


There's a requirement that an index in an aggregate be locally static (determined at analysis time), which prevents you from using a signal value.  That requirement is found in 9.3.3.3 Array aggregates, paragraph 7:


  Apart from a final element association with the single choice others, the rest (if any) of the element associations of an array aggregate shall be either all positional or all named. A named association of an array aggregate is allowed to have a choice that is not locally static, or likewise a choice that is a null range, only if the aggregate includes a single element association and this element association has a single choice. An others choice is locally static if the applicable index constraint is locally static.


If you follow the BNF from simple_expression through primary:

simple_expression ::=
     [ sign ] term { adding_operator term }

term ::=
     factor { multiplying_operator factor }

factor ::=
     primary [ ** primary ]
   | abs primary
   | not primary
   | logical_operator primary

primary ::= 
     name 
   | literal
   | aggregate
   | function_call
   | qualified_expression 
   | type_conversion
   | allocator
   | ( expression )


we find your name. You can look through 9.4.2 Locally static primaries and determine signals aren't mentioned, while a constant is (9.4.2 b).

So we see that your aggregate is not eligible to be taken as the value provided by the evaluation of the simple expression that is a signal name. If declared as a constant it would be: 

library ieee;
use ieee.std_logic_1164.all;

entity foo is
end entity;

architecture fum of foo is
    signal reg_clk_en: std_logic_vector(7 downto 0);
    constant write_reg: natural := 3;
begin
    reg_clk_en &lt;= (write_reg =&gt; '1', others =&gt; '0');
end architecture;


This analyzes, elaborates and simulates (while doing nothing particularly interesting).

The only other possible evaluation of the name as an index would be as an element name of a record, noting your code snippet isn't a minimal, complete and verifiable example (lacking declarations).

9.3.3 Aggregates, 9.3.3.1 General, paragraph 5:


  An element association with a choice that is an element simple name is only allowed in a record aggregate. An element association with a choice that is a simple expression or a discrete range is only allowed in an array aggregate: a simple expression specifies the element at the corresponding index value, whereas a discrete range specifies the elements at each of the index values in the range. ...


Assuming it's an array type the standard tells us a signal can't be used as an index for an aggregate in the manner you have attempted.

Non-authoritative resources can't always be relied on to fully define acceptable semantics.