wchen88
2017-08-10 15:47
采纳率: 100%
浏览 1.8k

正则表达式匹配并替换一段字符串

遇到一个需求是需要将数据库查询语言中的from后的所有字段全部原样取出,在from前加上select count(*), 如下

 " Select a from " + TbItem.class.getName() + " a " + " where a.id= :id"
 替换成
 “ Select count(*) from " + TbItem.class.getName() + " a " + " where a.id= :id”

或者

 "from Employee e where e.name = :name"
 替换成
 “select cout(*) from Employee e where e.name = :name”

因为有的语句没有select,所以要定位到from前替换

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • wchen88 2017-08-11 00:45
    已采纳

    public class AA {
    public static void main(String[] args) {
    String s=" Select a from xxx a " + " where a.id= :id";
    String regex = ".*(from.*)$";
    String result=s.replaceAll(regex,"select count(*) $1");
    System.out.println(result);
    }
    }
    其他网友的答案

    点赞 打赏 评论
  • Tsui丶 2017-08-11 00:26

    提供一种解决思路:获取sql字符串,根据from分割 str.split("from") 得到 “” 或者 “select XXX ”;
    根本不需要判断了,直接全部替换就可以了

    点赞 打赏 评论
  • Yirujet 2017-08-11 02:25

    楼主采纳的答案其实是有问题的,wchen88 提供的正则表达式".*(from.*)$"考虑的并不全面,在贪婪模式下,'.'字符会匹配from这四个字符前的
    尽可能多的字符。如果是单查询语句”select * from aa where ......”,这个正则表达式没有问题,会成功替换成"select count(*) from aa where...",
    可如果是子查询”select … from aa where id in(select id from bb where …)”,这个正则表达式就有问题了,在贪婪模式下,会被替换成”select count(*) from bb where …)”,显然是有问题的,
    所以正确的正则表达式应该设计成匹配from这4个字符前的文本时采用非贪婪模式,
    应是:(?:.*?)from(.*)
    在C#下,我是这样设计的:
    public string formatSql(string _strSql) {
    _strSql = "select * from aa where id in(select id from bb)";
    string _regExp = @"(?:.*?)from(.*)";
    string _strSqlCnt = "select count(*) from ";
    string _strFormatSql = "";
    MatchCollection _matchs = Regex.Matches(_strSql,_regExp,RegexOptions.IgnoreCase);
    foreach (Match match in _matchs) {
    GroupCollection _groups = match.Groups;
    string _strGroup = _groups[1].Value;
    _strFormatSql= _strSqlCnt + _strGroup;
    }
    return _strFormatSql;
    }

    点赞 打赏 评论

相关推荐 更多相似问题