although I've read a lot of similar questions here, I couldn't find the absolute solution. My task is to parse the protein names by removing the brackets and parentheses in the row. In short, I want to retain the words in front of any parentheses and brackets. But note that I need to keep symbols in the main words like H(+)/Cl(-) exchange transporter 6. data = { "Entry": ["A0A087X1C5", "A0A0B4J2F0", "O00468", "P51797", "O75164"], "Reviewed": ["reviewed"] * 5, "Entry Name": ["CP2D7_HUMAN", "PIOS1_HUMAN", "AGRIN_HUMAN", "CLCN6_HUMAN", "KDM4A_HUMAN"], "Protein names": [ "Putative cytochrome P450 2D7 (EC 1.14.14.1)", "Protein PIGBOS1 (PIGB opposite strand protein 1)", "Agrin [Cleaved into: Agrin N-terminal 110 kDa subunit; Agrin C-terminal 110 kDa subunit; Agrin C-terminal 90 kDa fragment (C90); Agrin C-terminal 22 kDa fragment (C22)]", "H(+)/Cl(-) exchange transporter 6 (Chloride channel protein 6) (ClC-6) (Chloride transport protein 6)", "Lysine-specific demethylase 4A (EC 1.14.11.66) (EC 1.14.11.69) (JmjC domain-containing histone demethylation protein 3A) (Jumonji domain-containing protein 2A) ([histone H3]-trimethyl-L-lysine(36) demethylase 4A) ([histone H3]-trimethyl-L-lysine(9) demethylase 4A)" ], "Gene Names": ["CYP2D7", "PIGBOS1", "AGRN AGRIN", "CLCN6 KIAA0046", "KDM4A JHDM3A JMJD2 JMJD2A KIAA0677"], "Length": [515, 54, 2068, 869, 1064], "STRING": [None, "9606.ENSP00000484893", "9606.ENSP00000368678", "9606.ENSP00000234488", "9606.ENSP00000361473"] } # Load into DataFrame df = pd.DataFrame(data) result = { "Entry": ["A0A087X1C5", "A0A0B4J2F0", "O00468", "P51797", "O75164"], "Reviewed": ["reviewed"] * 5, "Entry Name": ["CP2D7_HUMAN", "PIOS1_HUMAN", "AGRIN_HUMAN", "CLCN6_HUMAN", "KDM4A_HUMAN"], "Protein names": [ "Putative cytochrome P450 2D7", "Protein PIGBOS1", "Agrin", "H(+)/Cl(-) exchange transporter 6", "Lysine-specific demethylase 4A" ], "Gene Names": ["CYP2D7", "PIGBOS1", "AGRN AGRIN", "CLCN6 KIAA0046", "KDM4A JHDM3A JMJD2 JMJD2A KIAA0677"], "Length": [515, 54, 2068, 869, 1064], "STRING": [None, "9606.ENSP00000484893", "9606.ENSP00000368678", "9606.ENSP00000234488", "9606.ENSP00000361473"] } # Expected result result_df = pd.DataFrame(result) When I tried the first approach, it removed all parentheses and brackets without considering the intermediate symbols. df['Protein names'] = df["Protein names"].str.replace(r'\s*(\(|\[).*?(\)|\])\s*$', '', regex=True).str.strip() # Before # H(+)/Cl(-) exchange transporter 6 (Chloride channel protein 6) (ClC-6) (Chloride transport protein 6) # After # H Also, I tried the step-by-step process using the second code, but it removed the intermediate symbols, too. df["Protein names"] = df["Protein names"].str.split(' \(').str[0].str.strip() df["Protein names"] = df["Protein names"].str.split(' \[').str[0].str.strip() # Before # Very-long-chain (3R)-3-hydroxyacyl-CoA dehydratase 1 (EC 4.2.1.134) (3-hydroxyacyl-CoA dehydratase 1) (HACD1) (Cementum-attachment protein) (CAP) (Protein-tyrosine phosphatase-like member A) # After # Very-long-chain Thank you for reading this long question. I'm looking forward to your tips. Continue reading...