<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>浅 茉</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://baoyuzhang.github.io/"/>
  <updated>2019-11-21T08:49:42.087Z</updated>
  <id>https://baoyuzhang.github.io/</id>
  
  <author>
    <name>baoyuzhang</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>npm link的使用</title>
    <link href="https://baoyuzhang.github.io/2019/11/20/npm%20link%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
    <id>https://baoyuzhang.github.io/2019/11/20/npm link的使用/</id>
    <published>2019-11-20T10:17:38.000Z</published>
    <updated>2019-11-21T08:49:42.087Z</updated>
    
    <content type="html"><![CDATA[<ul><li>问题：开源项目多人共同开发，我开发的模块是一个单独的npm包，想要在自己的项目中直接引用开发中的模块进行调试和测试。</li><li>解决方法： npm link</li></ul><a id="more"></a><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://docs.npmjs.com/cli/link.html" target="_blank" rel="noopener">npm官网·npm-link</a><br><a href="https://www.cnblogs.com/pqjwyn/p/9626335.html" target="_blank" rel="noopener">博客·npm link中文文档</a><br><a href="https://www.jianshu.com/p/aaa7db89a5b2" target="_blank" rel="noopener">简书·npm link的使用</a></p><h2 id="一、在全局环境的node-modules中，创建开发中的模块链接"><a href="#一、在全局环境的node-modules中，创建开发中的模块链接" class="headerlink" title="一、在全局环境的node_modules中，创建开发中的模块链接"></a>一、在全局环境的node_modules中，创建开发中的模块链接</h2><p>此时github上的项目已经fork并clone到本地，切换到开发分支，在要开发的模块<code>uform/packages/react-schema-renderer</code>下，执行<code>npm link</code>。</p><p>这一步会以package.json中的name，在全局的node_modules中创建本地模块的链接，打开全局node_modules，会看到该链接：</p><p><img src="1.开发模块npm&#32;link.png" alt="开发模块npm link"></p><p><img src="2.全局node_modules.png" alt="全局node_modules"></p><h2 id="二、在自己的测试项目中引用链接"><a href="#二、在自己的测试项目中引用链接" class="headerlink" title="二、在自己的测试项目中引用链接"></a>二、在自己的测试项目中引用链接</h2><p>在自己的项目中，执行<code>npm link @uform/react-schema-renderer</code></p><p><img src="3.个人测试项目中引入链接.png" alt="个人测试项目中引入链接"></p><p>这一步会将上一步全局环境中创建的链接引入测试项目中，打开测试项目的node_modules可以看到该链接：</p><p><img src="4.个人测试项目中查看.png" alt="个人测试项目中查看"></p>]]></content>
    
    <summary type="html">
    
      &lt;ul&gt;
&lt;li&gt;问题：开源项目多人共同开发，我开发的模块是一个单独的npm包，想要在自己的项目中直接引用开发中的模块进行调试和测试。&lt;/li&gt;
&lt;li&gt;解决方法： npm link&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="npm" scheme="https://baoyuzhang.github.io/tags/npm/"/>
    
  </entry>
  
  <entry>
    <title>git config配置不同用户信息</title>
    <link href="https://baoyuzhang.github.io/2019/11/20/git-config%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF/"/>
    <id>https://baoyuzhang.github.io/2019/11/20/git-config配置不同用户信息/</id>
    <published>2019-11-20T07:11:24.000Z</published>
    <updated>2019-11-20T07:46:44.203Z</updated>
    
    <content type="html"><![CDATA[<p>本文介绍git的三个配置文件，以及不同仓库使用不同用户信息的方法。</p><a id="more"></a><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE" target="_blank" rel="noopener">git文档·初次运行 Git 前的配置</a><br><a href="https://www.cnblogs.com/wshiqtb/p/5160608.html" target="_blank" rel="noopener">git配置</a></p><h2 id="git的配置文件"><a href="#git的配置文件" class="headerlink" title="git的配置文件"></a>git的配置文件</h2><p>git通过配置文件来设置控制 Git 外观和行为，共有三个配置文件，权重为仓库级&gt;全局级&gt;系统级：</p><ol><li>系统级<code>--system</code>：/etc/gitconfig 文件，包含系统上每一个用户及他们仓库的通用配置；</li><li>全局级<code>--global</code>：~/.gitconfig 或 ~/.config/git/config 文件，只针对当前用户；</li><li>仓库级<code>--local</code>：.git/config，当前仓库的Git 目录中的 config 文件（就是 ）。</li></ol><h2 id="不同仓库使用不同用户信息"><a href="#不同仓库使用不同用户信息" class="headerlink" title="不同仓库使用不同用户信息"></a>不同仓库使用不同用户信息</h2><p>初次安装git时，曾执行如下命令设置你的用户名与邮件地址：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.name <span class="string">"John Doe"</span></span><br><span class="line">git config --global user.email johndoe@example.com</span><br></pre></td></tr></table></figure><p>因为使用了 –global 选项，无论你在该系统上做任何事情， Git 都会使用这些信息。这些信息会写入到你的每一次提交中，且不可更改。工作电脑通常会全局配置公司邮箱和用户名，那么当提交到个人github时，也会使用公司邮箱和用户名。</p><p>我们想要的是提交个人github仓库使用个人用户名和邮箱，以下方法任选其一：</p><p>&lt;方法一&gt;如下命令可修改仓库级配置：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config user.name <span class="string">"John Doe"</span></span><br><span class="line">git config user.email johndoe@example.com</span><br></pre></td></tr></table></figure><p>&lt;方法二&gt;打开仓库级配置文件修改：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">open .git/config</span><br></pre></td></tr></table></figure><p><img src="打开仓库级配置文件修改.png" alt="打开仓库级配置文件修改"></p><p>完成后，再提交代码，<code>git log</code>查看提交信息，就会看到个人信息配置成功：<br><img src="git&#32;log.png" alt="git log"></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本文介绍git的三个配置文件，以及不同仓库使用不同用户信息的方法。&lt;/p&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="Git" scheme="https://baoyuzhang.github.io/tags/Git/"/>
    
      <category term="Github" scheme="https://baoyuzhang.github.io/tags/Github/"/>
    
  </entry>
  
  <entry>
    <title>mac一台电脑配置多个git账号</title>
    <link href="https://baoyuzhang.github.io/2019/11/19/mac%E4%B8%80%E5%8F%B0%E7%94%B5%E8%84%91%E9%85%8D%E7%BD%AE%E5%A4%9A%E4%B8%AAgit%E8%B4%A6%E5%8F%B7/"/>
    <id>https://baoyuzhang.github.io/2019/11/19/mac一台电脑配置多个git账号/</id>
    <published>2019-11-19T09:37:46.000Z</published>
    <updated>2019-11-19T12:15:37.323Z</updated>
    
    <content type="html"><![CDATA[<p>工作环境使用gitlab账号，个人学习或参与开源项目需要使用github账号。默认情况下，一台电脑的Git只对应一个账户。本文教你在一个Git终端中配置多个账户，同时管理多个托管网站的代码。</p><a id="more"></a><p>参考资料<br><a href="https://www.jianshu.com/p/698f82e72415" target="_blank" rel="noopener">https://www.jianshu.com/p/698f82e72415</a><br><a href="https://segmentfault.com/a/1190000016269686" target="_blank" rel="noopener">https://segmentfault.com/a/1190000016269686</a></p><h2 id="1-查看已配置的git列表"><a href="#1-查看已配置的git列表" class="headerlink" title="1. 查看已配置的git列表"></a>1. 查看已配置的git列表</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git config --list</span><br></pre></td></tr></table></figure><p>已有公司的ssh-key<br><img src="1.查看已配置的git列表.png" alt="1.查看已配置的git列表"></p><h2 id="2-生成github-SSH-key"><a href="#2-生成github-SSH-key" class="headerlink" title="2. 生成github SSH key"></a>2. 生成github SSH key</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa -f ~/.ssh/id_rsa_github -C <span class="string">"baoyuzhang@126.com"</span></span><br></pre></td></tr></table></figure><p><img src="2.&#32;生成github&#32;SSH&#32;key.png" alt="2. 生成github SSH key"></p><h2 id="3-添加到ssh-agent信任列表"><a href="#3-添加到ssh-agent信任列表" class="headerlink" title="3. 添加到ssh-agent信任列表"></a>3. 添加到ssh-agent信任列表</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-add ~/.ssh/id_rsa</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-add ~/.ssh/id_rsa_github</span><br></pre></td></tr></table></figure><p><img src="3.&#32;添加到ssh-agent信任列表.png" alt="3. 添加到ssh-agent信任列表"></p><p>为了检验本地是否添加成功，可以使用<code>ssh-add -l</code>命令进行查看</p><h2 id="4-添加公钥到你的github"><a href="#4-添加公钥到你的github" class="headerlink" title="4. 添加公钥到你的github"></a>4. 添加公钥到你的github</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pbcopy &lt; ~/.ssh/id_rsa_github.pub</span><br></pre></td></tr></table></figure><h2 id="5-在config文件配置多个ssh-key"><a href="#5-在config文件配置多个ssh-key" class="headerlink" title="5. 在config文件配置多个ssh-key"></a>5. 在config文件配置多个ssh-key</h2><p>打开目录，看看有没有config文件，没有的话新建一个</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">open ~/.ssh/</span><br></pre></td></tr></table></figure><p>分别配置公司和自己的ssh-key</p><table><thead><tr><th>键</th><th>值</th><th>规则</th></tr></thead><tbody><tr><td>Host</td><td>主机</td><td>随意写，有点关联就行了</td></tr><tr><td>Hostname</td><td>主机名</td><td>公司gitlab域名，必须写正确</td></tr><tr><td>IdentityFile</td><td>身份文件</td><td>rsa具体路径地址</td></tr><tr><td>User</td><td>用户</td><td>可随意写，建议使用Host的前面部分，后面具体clone操作都会用到这个user</td></tr></tbody></table><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#公司</span></span><br><span class="line">Host company</span><br><span class="line">Hostname <span class="comment">#公司gitlab域名#</span></span><br><span class="line">IdentityFile ~/.ssh/id_rsa</span><br><span class="line">User company</span><br><span class="line">  </span><br><span class="line"><span class="comment">#个人</span></span><br><span class="line">Host github</span><br><span class="line">Hostname github.com</span><br><span class="line">IdentityFile ~/.ssh/id_rsa_github</span><br><span class="line">User github</span><br></pre></td></tr></table></figure><h2 id="6-连接测试"><a href="#6-连接测试" class="headerlink" title="6. 连接测试"></a>6. 连接测试</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -T <span class="comment">#公司gitlab域名#</span></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -T git@github.com</span><br></pre></td></tr></table></figure><p><img src="6.连接测试.png" alt="6.连接测试"></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;工作环境使用gitlab账号，个人学习或参与开源项目需要使用github账号。默认情况下，一台电脑的Git只对应一个账户。本文教你在一个Git终端中配置多个账户，同时管理多个托管网站的代码。&lt;/p&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="Git" scheme="https://baoyuzhang.github.io/tags/Git/"/>
    
      <category term="Github" scheme="https://baoyuzhang.github.io/tags/Github/"/>
    
  </entry>
  
  <entry>
    <title>正则表达式</title>
    <link href="https://baoyuzhang.github.io/2017/05/19/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
    <id>https://baoyuzhang.github.io/2017/05/19/正则表达式/</id>
    <published>2017-05-19T11:42:10.000Z</published>
    <updated>2017-05-19T12:18:49.000Z</updated>
    
    <content type="html"><![CDATA[<p>前端会遇到很多字符串验证问题，正则表达式是一个强大的字符串匹配工具，今天就来总结一下正则表达式。</p><a id="more"></a><h1 id="（一）工具"><a href="#（一）工具" class="headerlink" title="（一）工具"></a>（一）工具</h1><p><a href="https://regexper.com/" target="_blank" rel="noopener">Regexper</a>：正则表达式可视化工具，看不懂的表达式放进去，帮助理解</p><h1 id="（二）理论部分"><a href="#（二）理论部分" class="headerlink" title="（二）理论部分"></a>（二）理论部分</h1><h2 id="一、正则表达式简介"><a href="#一、正则表达式简介" class="headerlink" title="一、正则表达式简介"></a>一、正则表达式简介</h2><p>正则表达式是一个强大的字符串匹配工具。</p><h3 id="1-匹配模式标志flags"><a href="#1-匹配模式标志flags" class="headerlink" title="1.匹配模式标志flags"></a>1.匹配模式标志flags</h3><blockquote><p>3 个匹配模式标志flags：标明正则表达式的行为</p></blockquote><blockquote><p>一个正则表达式就是一个模式与3 个标志的组合体</p></blockquote><table><thead><tr><th>字 符</th><th>含 义</th></tr></thead><tbody><tr><td><code>g</code></td><td>执行一个全局匹配，简言之，就是要找到所有的匹配，而不是在找到一个之后就停止</td></tr><tr><td><code>m</code></td><td>多行匹配模式，^匹配一行的开头和字符串的开头，$匹配行的结束和字符串的结束</td></tr><tr><td><code>i</code></td><td>执行不区分大小写的匹配</td></tr></tbody></table><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pattern1 = <span class="regexp">/at/g</span>; <span class="comment">// 匹配字符串中所有"at"的实例</span></span><br><span class="line"><span class="keyword">var</span> pattern2 = <span class="regexp">/[bc]at/i</span>; <span class="comment">// 匹配第一个"bat"或"cat"，不区分大小写</span></span><br><span class="line"><span class="keyword">var</span> pattern3 = <span class="regexp">/.at/gi</span>; <span class="comment">// 匹配所有以"at"结尾的3 个字符的组合，不区分大小写</span></span><br></pre></td></tr></table></figure><h3 id="2-元字符"><a href="#2-元字符" class="headerlink" title="2.元字符"></a>2.元字符</h3><blockquote><p>与其他语言中的正则表达式类似，匹配字符串中的元字符必须转义。</p></blockquote><p>正则表达式中的元字符包括：( [ { \ ^ $ | ) ? * + . ] }</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pattern1 = <span class="regexp">/[bc]at/i</span>; <span class="comment">// 匹配第一个"bat"或"cat"，不区分大小写</span></span><br><span class="line"><span class="keyword">var</span> pattern2 = <span class="regexp">/\[bc\]at/i</span>; <span class="comment">// 匹配第一个" [bc]at"，不区分大小写</span></span><br><span class="line"><span class="keyword">var</span> pattern3 = <span class="regexp">/.at/gi</span>; <span class="comment">// 匹配所有以"at"结尾的3 个字符的组合，不区分大小写</span></span><br><span class="line"><span class="keyword">var</span> pattern4 = <span class="regexp">/\.at/gi</span>; <span class="comment">// 匹配所有".at"，不区分大小写</span></span><br></pre></td></tr></table></figure><h3 id="3-创建正则表达式"><a href="#3-创建正则表达式" class="headerlink" title="3.创建正则表达式"></a>3.创建正则表达式</h3><blockquote><p>有两种方法，这两种方法完全等价。</p></blockquote><h4 id="lt-法一-gt-对象字面量"><a href="#lt-法一-gt-对象字面量" class="headerlink" title="&lt;法一&gt; 对象字面量"></a>&lt;法一&gt; 对象字面量</h4><ul><li>正则表达式放在一对斜杠（/）之间</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> expression = <span class="regexp">/ pattern /</span> flags ;</span><br></pre></td></tr></table></figure><h4 id="lt-法二-gt-使用RegExp-构造函数"><a href="#lt-法二-gt-使用RegExp-构造函数" class="headerlink" title="&lt;法二&gt; 使用RegExp()构造函数"></a>&lt;法二&gt; 使用RegExp()构造函数</h4><ul><li>2个参数（均为字符串）：要匹配的字符串模式pattern，（可选）匹配模式标志flags</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pattern1 = <span class="regexp">/[bc]at/i</span>; <span class="comment">// 匹配第一个"bat"或"cat"，不区分大小写</span></span><br><span class="line"><span class="keyword">var</span> pattern2 = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"[bc]at"</span>, <span class="string">"i"</span>); <span class="comment">// 与pattern1 相同，只不过是使用构造函数创建的</span></span><br></pre></td></tr></table></figure><p><strong>注意！</strong></p><ol><li>传递给RegExp 构造函数的2个参数都是字符串（不能把正则表达式字面量传递给RegExp 构造函数）</li><li>由于RegExp 构造函数的模式参数是字符串，所以在某些情况下要对字符进行<strong>双重转义</strong>：<ul><li>所有元字符</li><li>已经转义过的字符，例如：<code>\n</code>（字符<code>\</code>：在字符串中转义<code>\\</code>，在正则表达式字符串中双重转义<code>\\\\</code>）</li></ul></li></ol><table><thead><tr><th>字面量模式</th><th>等价的字符串</th></tr></thead><tbody><tr><td><code>/\[bc\]at/</code></td><td><code>&quot;\\[bc\\]at&quot;</code></td></tr><tr><td><code>/\.at/</code></td><td><code>&quot;\\.at&quot;</code></td></tr><tr><td><code>/name\/age/</code></td><td><code>&quot;name\\/age&quot;</code></td></tr><tr><td><code>/\d.\d{1,2}/</code></td><td><code>&quot;\\d.\\d{1,2}&quot;</code></td></tr><tr><td><code>/\w\\hello\\123/</code></td><td><code>&quot;\\w\\\\hello\\\\123&quot;</code></td></tr></tbody></table><h2 id="二、RegExp类型"><a href="#二、RegExp类型" class="headerlink" title="二、RegExp类型"></a>二、RegExp类型</h2><p>EMCAScript通过RegExp类型来支持正则表达式。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"\\d&#123;5&#125;"</span>,<span class="string">"g"</span>);<span class="comment">//匹配全局模式下的5个数字</span></span><br><span class="line">alert(reg.test(<span class="string">"1J2a35786"</span>));<span class="comment">//true</span></span><br><span class="line">alert(reg.test(<span class="string">"1J2a356"</span>));<span class="comment">//false</span></span><br></pre></td></tr></table></figure><p><strong>局限性</strong></p><blockquote><p>要了解更多相关信息，请访问<a href="http://www.regular-expressions.info" target="_blank" rel="noopener">www.regular-expressions.info</a></p></blockquote><p>尽管ECMAScript 中的正则表达式功能还是比较完备的，但仍然缺少某些语言（特别是Perl）所支<br>持的高级正则表达式特性。下面列出了ECMAScript 正则表达式不支持的特性:</p><ul><li>匹配字符串开始和结尾的\A 和\Z 锚【但支持以插入符号（^）和美元符号（$）来匹配字符串的开始和结尾】</li><li>向后查找（lookbehind）【但完全支持向前查找（lookahead）】</li><li>并集和交集类</li><li>原子组（atomic grouping）</li><li>Unicode 支持（单个字符除外，如\uFFFF）</li><li>命名的捕获组【但支持编号的捕获组】</li><li>s（single，单行）和x（free-spacing，无间隔）匹配模式</li><li>条件匹配</li><li>正则表达式注释</li></ul><p>即使存在这些限制，ECMAScript 正则表达式仍然是非常强大的，能够帮我们完成绝大多数模式匹<br>配任务。</p><h3 id="1-RegExp构造函数属性"><a href="#1-RegExp构造函数属性" class="headerlink" title="1. RegExp构造函数属性"></a>1. RegExp构造函数属性</h3><p>适用于作用域中的所有正则表达式，并且基于所执行的最近一次正则表达式操作而变化。</p><p>可以通过两种方式访问：长属性名、短属性名（Opera 是例外，它不支持短属性名）</p><table><thead><tr><th>长属性名</th><th>短属性名</th><th>说 明</th></tr></thead><tbody><tr><td>input</td><td>$_</td><td>原始字符串。Opera未实现此属性</td></tr><tr><td>lastMatch</td><td>$&amp;</td><td>最近一次与整个正则表达式匹配的项。Opera未实现此属性</td></tr><tr><td>lastParen</td><td>$+</td><td>最近一次匹配的捕获组。Opera未实现此属性</td></tr><tr><td>leftContext</td><td>$&apos;</td><td>input字符串中lastMatch之前的文本</td></tr><tr><td>multiline</td><td>$*</td><td>布尔值，表示是否所有表达式都使用多行模式。IE和Opera未实现此属性</td></tr><tr><td>rightContext</td><td>$’</td><td>Input字符串中lastMatch之后的文本</td></tr><tr><td></td><td>RegExp.$n（1&lt;=n&lt;=9）</td><td>存储第n个匹配的捕获组</td></tr></tbody></table><p>短属性名大多不是有效的ECMAScript 标识符，必须通过方括号语法来访问。</p><p>使用这些属性可以从exec()或test()执行的操作中提取出更具体的信息：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"this has been a short summer"</span>;</span><br><span class="line"><span class="keyword">var</span> pattern = <span class="regexp">/(..)or(.)/g</span>;</span><br><span class="line"><span class="keyword">if</span> (pattern.test(text))&#123;</span><br><span class="line">alert(<span class="built_in">RegExp</span>.$<span class="number">1</span>); <span class="comment">//sh</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.$<span class="number">2</span>); <span class="comment">//t</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"this has been a short summer"</span>;</span><br><span class="line"><span class="keyword">var</span> pattern = <span class="regexp">/(.)hort/g</span>;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">* 注意：Opera 不支持input、lastMatch、lastParen 和multiline 属性</span></span><br><span class="line"><span class="comment">* Internet Explorer 不支持multiline 属性</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">if</span> (pattern.test(text))&#123;</span><br><span class="line">alert(<span class="built_in">RegExp</span>.input); <span class="comment">// this has been a short summer</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.leftContext); <span class="comment">// this has been a</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.rightContext); <span class="comment">// summer</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.lastMatch); <span class="comment">// short</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.lastParen); <span class="comment">// s</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>.multiline); <span class="comment">// false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"this has been a short summer"</span>;</span><br><span class="line"><span class="keyword">var</span> pattern = <span class="regexp">/(.)hort/g</span>;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">* 注意：Opera 不支持input、lastMatch、lastParen 和multiline 属性</span></span><br><span class="line"><span class="comment">* Internet Explorer 不支持multiline 属性</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">if</span> (pattern.test(text))&#123;</span><br><span class="line">alert(<span class="built_in">RegExp</span>.$_); <span class="comment">// this has been a short summer</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>[<span class="string">"$`"</span>]); <span class="comment">// this has been a</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>[<span class="string">"$'"</span>]); <span class="comment">// summer</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>[<span class="string">"$&amp;"</span>]); <span class="comment">// short</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>[<span class="string">"$+"</span>]); <span class="comment">// s</span></span><br><span class="line">alert(<span class="built_in">RegExp</span>[<span class="string">"$*"</span>]); <span class="comment">// false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="2-RegExp实例属性"><a href="#2-RegExp实例属性" class="headerlink" title="2. RegExp实例属性"></a>2. RegExp实例属性</h3><p>通过这些属性可以获知一个正则表达式的各方面信息，但却没有多大用处，因为这些信息全都包含在模式声明中。</p><table><thead><tr><th>属性名</th><th>类型</th><th>属性</th><th>含义</th></tr></thead><tbody><tr><td>global</td><td>布尔值</td><td>只读</td><td>是否设置了<code>g</code>标志</td></tr><tr><td>multiline</td><td>布尔值</td><td>只读</td><td>是否设置了<code>m</code>标志</td></tr><tr><td>ignoreCase</td><td>布尔值</td><td>只读</td><td>是否设置了<code>i</code>标志</td></tr><tr><td>source</td><td>字符串</td><td>只读</td><td>规范形式的字符串，即字面量形式所用的字符串，而非传入构造函数中的字符串模式</td></tr><tr><td>lastIndex</td><td>整数</td><td>只读</td><td>继续下一次检索的开始位置</td></tr></tbody></table><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pattern1 = <span class="regexp">/\[bc\]at/i</span>;</span><br><span class="line">alert(pattern1.global); <span class="comment">//false</span></span><br><span class="line">alert(pattern1.ignoreCase); <span class="comment">//true</span></span><br><span class="line">alert(pattern1.multiline); <span class="comment">//false</span></span><br><span class="line">alert(pattern1.lastIndex); <span class="comment">//0</span></span><br><span class="line">alert(pattern1.source); <span class="comment">//"\[bc\]at"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> pattern2 = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"\\[bc\\]at"</span>, <span class="string">"i"</span>);</span><br><span class="line">alert(pattern2.global); <span class="comment">//false</span></span><br><span class="line">alert(pattern2.ignoreCase); <span class="comment">//true</span></span><br><span class="line">alert(pattern2.multiline); <span class="comment">//false</span></span><br><span class="line">alert(pattern2.lastIndex); <span class="comment">//0</span></span><br><span class="line">alert(pattern2.source); <span class="comment">//"\[bc\]at"</span></span><br></pre></td></tr></table></figure><h3 id="3-RegExp实例方法"><a href="#3-RegExp实例方法" class="headerlink" title="3. RegExp实例方法"></a>3. RegExp实例方法</h3><h4 id="a-exec-：查找匹配字符串和捕获组"><a href="#a-exec-：查找匹配字符串和捕获组" class="headerlink" title="a.exec()：查找匹配字符串和捕获组"></a>a.<code>exec()</code>：查找匹配字符串和捕获组</h4><ul><li>参数：正则表达式</li><li>返回：由匹配项组成的数组；没有匹配项返回null<ul><li>返回数组，第一项是与整个模式匹配<br>的字符串，其他项是与捕获组匹配的字符串（如果模式中没有捕获组，则该数组只包含一项）<ul><li>假设macth()返回一个数组a，那么a[n]存放的是$n的内容：a[0]存放的是完整的匹配，a[1]存放的是第一个捕获组，以此类推。</li></ul></li><li>返回数组属性：<ul><li>index ：匹配项在字符串中的位置</li><li>input ：待解析字符串</li></ul></li></ul></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"mom and dad and baby"</span>;</span><br><span class="line"><span class="keyword">var</span> pattern = <span class="regexp">/mom( and dad( and baby)?)?/gi</span>;</span><br><span class="line"><span class="keyword">var</span> matches = pattern.exec(text);</span><br><span class="line">alert(matches.index); <span class="comment">// 0</span></span><br><span class="line">alert(matches.input); <span class="comment">// "mom and dad and baby"</span></span><br><span class="line">alert(matches[<span class="number">0</span>]); <span class="comment">// "mom and dad and baby"</span></span><br><span class="line">alert(matches[<span class="number">1</span>]); <span class="comment">// " and dad and baby"</span></span><br><span class="line">alert(matches[<span class="number">2</span>]); <span class="comment">// " and baby"</span></span><br></pre></td></tr></table></figure><p><strong>说明</strong></p><p>exec()方法：即使在模式中设置了全局标志<code>g</code>，它每次也只会返回一个匹配项：</p><ul><li><p>不设置全局标志<code>g</code>：在同一个字符串上多次调用exec()将始终返回第一个匹配项的信息：</p><p>（特例：IE 在非全局模式下，lastIndex 属性每次也会变化）</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"cat, bat, sat, fat"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> pattern1 = <span class="regexp">/.at/</span>;</span><br><span class="line"><span class="keyword">var</span> matches = pattern1.exec(text);</span><br><span class="line"></span><br><span class="line">alert(matches.index); <span class="comment">//0</span></span><br><span class="line">alert(matches[<span class="number">0</span>]); <span class="comment">//cat</span></span><br><span class="line">alert(pattern1.lastIndex); <span class="comment">//0</span></span><br><span class="line">matches = pattern1.exec(text);</span><br><span class="line">alert(matches.index); <span class="comment">//0</span></span><br><span class="line">alert(matches[<span class="number">0</span>]); <span class="comment">//cat</span></span><br><span class="line">alert(pattern1.lastIndex); <span class="comment">//0</span></span><br></pre></td></tr></table></figure></li><li><p>设置全局标志<code>g</code>：每次调用exec()会在字符串中继续查找新匹配项：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"cat, bat, sat, fat"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> pattern2 = <span class="regexp">/.at/g</span>;</span><br><span class="line"><span class="keyword">var</span> matches = pattern2.exec(text);</span><br><span class="line"></span><br><span class="line">alert(matches.index); <span class="comment">//0</span></span><br><span class="line">alert(matches[<span class="number">0</span>]); <span class="comment">//cat</span></span><br><span class="line">alert(pattern2.lastIndex); <span class="comment">//3</span></span><br><span class="line">matches = pattern2.exec(text);</span><br><span class="line">alert(matches.index); <span class="comment">//5</span></span><br><span class="line">alert(matches[<span class="number">0</span>]); <span class="comment">//bat</span></span><br><span class="line">alert(pattern2.lastIndex); <span class="comment">//8</span></span><br></pre></td></tr></table></figure></li></ul><h4 id="b-test-：判断待解析字符串是否与此模式匹配"><a href="#b-test-：判断待解析字符串是否与此模式匹配" class="headerlink" title="b.test()：判断待解析字符串是否与此模式匹配"></a>b.<code>test()</code>：判断待解析字符串是否与此模式匹配</h4><ul><li>参数：待解析字符串</li><li>模式与参数匹配：返回true；否则，返回false</li></ul><p>在只想知道目标字符串与某个模式是否匹配，但不需要知道其文本内容时，使用这个方法非常方便。因此，test()方法经常被用在if 语句中：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> text = <span class="string">"000-00-0000"</span>;</span><br><span class="line"><span class="keyword">var</span> pattern = <span class="regexp">/\d&#123;3&#125;-\d&#123;2&#125;-\d&#123;4&#125;/</span>;</span><br><span class="line"><span class="keyword">if</span> (pattern.test(text))&#123;</span><br><span class="line">alert(<span class="string">"The pattern was matched."</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h4 id="c-继承的方法"><a href="#c-继承的方法" class="headerlink" title="c.继承的方法"></a>c.继承的方法</h4><ul><li>valueOf()方法：返回正则表达式本身</li><li>toLocaleString()方法：返回正则表达式的字面量，与创建正则表达式的方式无关</li><li>toString()方法：返回正则表达式的字面量，与创建正则表达式的方式无关<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pattern = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"\\[bc\\]at"</span>, <span class="string">"gi"</span>);</span><br><span class="line">alert(pattern.toString()); <span class="comment">// /\[bc\]at/gi</span></span><br><span class="line">alert(pattern.toLocaleString()); <span class="comment">// /\[bc\]at/gi</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="三、待解析字符串的string方法"><a href="#三、待解析字符串的string方法" class="headerlink" title="三、待解析字符串的string方法"></a>三、待解析字符串的string方法</h2><h3 id="1-search-：查找匹配字符串位置"><a href="#1-search-：查找匹配字符串位置" class="headerlink" title="1. search()：查找匹配字符串位置"></a>1. <code>search()</code>：查找匹配字符串位置</h3><ul><li>参数：正则表达式</li><li>返回：匹配子串的起始位置；未找到返回-1.<ul><li>例: <code>JavaScript.search(/script/i);//返回4</code></li></ul></li></ul><p><strong>说明</strong>：<code>search()</code>方法不支持全局属性检索，所以会忽略匹配模式标志g</p><h3 id="2-replace-：替换"><a href="#2-replace-：替换" class="headerlink" title="2. replace()：替换"></a>2. <code>replace()</code>：替换</h3><ul><li>2个参数：正则，作为替换的字符串<ul><li>若第一个参数是字符串，<code>replace()</code>则会直接搜索这个字符串</li><li>若作为替换字符串中出现了<code>$数字</code>，那么<code>replace()</code>将用与指定的子表达式相匹配的文本来替换这两个字符</li></ul></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">text.replace(<span class="regexp">/javascript/gi</span>,<span class="string">"JavaScript"</span>);<span class="comment">//将所有不区分大小写的javascript都替换成大小写正确的JavaScript</span></span><br><span class="line"><span class="comment">//一段引用文本起始于引号，结束与引号</span></span><br><span class="line"><span class="comment">//中间的内容区域，不能包含引号</span></span><br><span class="line"><span class="keyword">var</span> quote = <span class="regexp">/"([^"]*)"/g</span>;</span><br><span class="line"><span class="comment">//引用中文半角引号替换英文引号，同时要保持引号之间的内容(储存在$1中)没有被修改</span></span><br><span class="line">text.replace(quote,<span class="string">'“$1”'</span>);</span><br></pre></td></tr></table></figure><h3 id="3-match-：查找匹配字符串和捕获组"><a href="#3-match-：查找匹配字符串和捕获组" class="headerlink" title="3. match()：查找匹配字符串和捕获组"></a>3. <code>match()</code>：查找匹配字符串和捕获组</h3><ul><li>参数：正则表达式</li><li>返回：由匹配结果组成的数组</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"1 plus 2 equals 3"</span>.match(<span class="regexp">/\d+/g</span>);<span class="comment">//返回["1","2","3"]</span></span><br></pre></td></tr></table></figure><p><strong>说明</strong></p><ul><li><code>match()</code>始终返回一个数组。若没有匹配模式标志g，只检索第一个匹配，则数组的第一个元素是匹配的字符串，余下的元素是正则表达式中的捕获组（用圆括号括起来的子表达式）。<ul><li>假设macth()返回一个数组a，那么a[n]存放的是$n的内容：a[0]存放的是完整的匹配，a[1]存放的是第一个捕获组，以此类推。</li></ul></li></ul><ul><li>例：解析一个url</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> url = <span class="regexp">/(\w+):\/\/([\w.]+)\/(\S*)/</span>;</span><br><span class="line"><span class="keyword">var</span> text = <span class="string">"Visit my blog at http://www.example.com/~david"</span>;</span><br><span class="line"><span class="keyword">var</span> result = text.match(url);</span><br><span class="line"><span class="keyword">if</span> (result != <span class="literal">null</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> fullurl = result[<span class="number">0</span>]; <span class="comment">//包含 "http://www.example.com/"</span></span><br><span class="line">    <span class="keyword">var</span> protocol = result[<span class="number">1</span>]; <span class="comment">//包含 "http"</span></span><br><span class="line">    <span class="keyword">var</span> host = result[<span class="number">2</span>]; <span class="comment">//包含 "www.example.com"</span></span><br><span class="line">    <span class="keyword">var</span> path = result[<span class="number">3</span>]; <span class="comment">//包含~david</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-split-：分隔"><a href="#4-split-：分隔" class="headerlink" title="4. split()：分隔"></a>4. <code>split()</code>：分隔</h3><ul><li>参数：字符串/正则表达式</li><li><p>将字符串用传入的分隔符拆分为子串，返回：子串组成的数组</p></li><li><p>例：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 参数为字符串</span></span><br><span class="line"><span class="string">"123,456,789"</span>.split(<span class="string">","</span>);<span class="comment">//返回["123","456","789"]</span></span><br><span class="line"><span class="comment">// 参数为正则表达式</span></span><br><span class="line"><span class="string">"1,2, 3,4 ,5"</span>.split(<span class="regexp">/\s*,\s*/</span>)<span class="comment">//返回["1","2"," 3","4 ","5"]，指定分隔符”,”，允许两边留有任意多的空白符</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="四、正则表达式语法"><a href="#四、正则表达式语法" class="headerlink" title="四、正则表达式语法"></a>四、正则表达式语法</h2><h3 id="1-转义字符"><a href="#1-转义字符" class="headerlink" title="1.转义字符"></a>1.转义字符</h3><blockquote><p>非字母的字符匹配，这些字符需要通过反斜线（\）作前缀进行转义.</p></blockquote><table><thead><tr><th>字 符</th><th>匹 配</th><th>举 例</th></tr></thead><tbody><tr><td>字母和数字字符</td><td>自身</td><td></td></tr><tr><td><code>\o</code></td><td>NUL字符</td><td></td></tr><tr><td><code>\t</code></td><td>制表符</td><td></td></tr><tr><td><code>\n</code></td><td>换行符</td><td></td></tr><tr><td><code>\v</code></td><td>垂直制表符</td><td></td></tr><tr><td><code>\f</code></td><td>换页符</td><td></td></tr><tr><td><code>\r</code></td><td>回车符</td><td></td></tr><tr><td><code>\xnn</code></td><td>由十六进制数nn指定的拉丁字符</td><td><code>\x0A</code>等价于<code>\n</code></td></tr><tr><td><code>\uxxxx</code></td><td>由十六进制数xxxx指定的unicode字符</td><td><code>\u0009</code>等价于<code>\t</code></td></tr><tr><td><code>\cX</code></td><td>控制字符^X</td><td><code>\cJ</code>等价于换行符<code>\n</code></td></tr></tbody></table><p><strong>具有特殊含义的符号（元字符）</strong></p><pre><code>| \ / ( ) [ ] { }  . : ! * + = ^ ? $</code></pre><p>想要在正则表达式中对这些字符进行匹配，必须使用前缀”\”</p><p>其他标点符号（比如@和引号）无特殊含义，无需转义，直接使用即可。</p><h3 id="2-字符类"><a href="#2-字符类" class="headerlink" title="2.字符类"></a>2.字符类</h3><p>方括号：或/范围</p><blockquote><p>将直接量字符单独放进方括号内就组成了字符类。一个字符类可以匹配它包含的任意字符。<strong>字符类可以使用连字符来表示字符范围。</strong></p></blockquote><table><thead><tr><th>字 符</th><th>含 义</th></tr></thead><tbody><tr><td><code>.</code></td><td>除换行符和unicode行终止符之外的任意字符</td></tr><tr><td><code>[...]</code></td><td>方括号内的任意字符，“或”的关系</td></tr><tr><td><code>[^...]</code></td><td>不在方括号内的任意字符</td></tr><tr><td><code>\w</code></td><td>任何ASCII符组成的单词，等同<code>[a-zA-Z0-9]</code></td></tr><tr><td><code>\W</code></td><td>任何不是ASCII符组成的的单词，等同<code>[^a-zA-Z0-9]</code></td></tr><tr><td><code>\s</code></td><td>任何unicode空白字符</td></tr><tr><td><code>\S</code></td><td>任何非unicode空白符的字符，注意<code>\W</code>与<code>\s</code>不同</td></tr><tr><td><code>\d</code></td><td>任何ASCII数字等价于<code>[0-9]</code></td></tr><tr><td><code>\D</code></td><td>除了ASCII数字之外的任何字符,等价于<code>[^0-9]</code></td></tr><tr><td><code>[\b]</code></td><td>退格直接量（特例）</td></tr></tbody></table><ul><li>例:<ul><li><code>/[a,b,c]/</code>：表示和字母”a”,”b”,”c”中的任意一个都匹配</li><li><code>/[a-z]/</code>：匹配拉丁字母表中的小写字母</li><li><code>/[\s\d]/</code>：匹配任意空白符或数字</li></ul></li></ul><h3 id="3-重复"><a href="#3-重复" class="headerlink" title="3.重复"></a>3.重复</h3><blockquote><p>用以指定字符重复的标记</p></blockquote><table><thead><tr><th>字 符</th><th>含 义</th></tr></thead><tbody><tr><td><code>{n,m}</code></td><td>匹配前一项至少n次，但不能超过m次</td></tr><tr><td><code>{n,}</code></td><td>匹配前一项n次，或者更多次</td></tr><tr><td><code>{n}</code></td><td>匹配前一项n次</td></tr><tr><td><code>?</code></td><td>匹配前一项0次或者1次，也就是前一项是可选的，等价于{0,1}</td></tr><tr><td><code>*</code></td><td>匹配前一项0次或者多次，等价于{0,}</td></tr><tr><td><code>+</code></td><td>匹配前一项1次或者多次看，等价于{1,}</td></tr></tbody></table><ul><li><p>例:</p><ul><li><code>/\d{2,4}/</code>:匹配2-4个数字。</li><li><code>/\w{3}\d?/</code>:精确匹配三个单词和一个可选的数字。</li><li><code>/\s+java\s+/</code>:匹配前后有1个或多个空格的字符串”java”</li><li><code>/[^(]*/</code>:匹配0个或多个非左括号的字符(这里实际上能与<code>&quot;(&quot;</code>匹配)</li></ul></li></ul><p><strong>注意！</strong></p><p>a. <code>*</code>和<code>?</code>能匹配0个字符。因此可以什么都不匹配</p><ul><li><p>例:</p><ul><li><code>/a*/</code>能匹配字符串”bbbb”，因其含有0个a。</li></ul></li></ul><p>b. 上表中列出的匹配字符为”贪婪的”匹配</p><p>  <strong>贪婪匹配</strong> ：尽可能多地匹配，且允许后续的正则表达式继续匹配</p><p>  <strong>非贪婪匹配</strong> ：只匹配一次，在待匹配的字符后跟随一个问号即可，<code>?</code>，<code>+?</code>，<code>*?</code>或<code>{1,5}?</code></p><ul><li>例:<ul><li><code>/a+/</code>：匹配“aaa”时，三个字符都被匹配,</li><li><code>/a+?/</code>：匹配“aaa”时，只匹配第一个a</li></ul></li></ul><h3 id="4-选择-分组和引用"><a href="#4-选择-分组和引用" class="headerlink" title="4.选择-分组和引用"></a>4.选择-分组和引用</h3><blockquote><p>包括：指定选择项，自表达式分组，引用前一子表达式的特殊字符</p></blockquote><ul><li>选择项的尝试匹配次序是从左到右，直到发现匹配项，若左边成功匹配就忽略右边的项。</li><li>正则表达式中圆括号的作用：<br>  a.  把单独的项组成子表达式，以便于可以像处理独立单元一样，用<code>\|</code>,<code>*</code>,<code>+</code>或者<code>?</code>等等来对单元内的项进行处理<br>  b.  在完整的模式中定义子模式<br>  c.  允许在同一正则表达式的后部,引用前面的子表达式</li></ul><table><thead><tr><th>字 符</th><th>含 义</th></tr></thead><tbody><tr><td>&#124;</td><td>选择：匹配该符号左/右的子表达式</td></tr><tr><td><code>(...)</code></td><td>组合+记忆：将几个项组合成为一个单元，该单元可通过&#124; * + ?等符号加以修饰，且可以记住和这个相匹配的字符串，供以后的引用使用</td></tr><tr><td><code>(?:..)</code></td><td>只组合不记忆：把项组合到一个单元，但不记忆与该组相匹配的字符</td></tr><tr><td><code>\n</code></td><td>和第n个分组第一次匹配的字符相匹配，组是圆括号中的子表达式（也有可能嵌套的），组索引是从左到右的左括号数,”(?:形式的分组不编码”</td></tr></tbody></table><ul><li>例:<ul><li><code>/ab|cd|ef/</code>：可以匹配”ab”，也可以匹配”cd”，还可以匹配”ef”</li><li><code>/\d{3}|[a-z]{4}/</code>：可以匹配3个数字，或者4个小写字母</li><li><code>(/[a-z]+(\d+)/)</code>：匹配一个或多个小写字母后跟随了一位或多位数字，使用括号包裹后，可以从检索到的匹配中抽取数字了</li></ul></li></ul><h3 id="5-指定匹配位置"><a href="#5-指定匹配位置" class="headerlink" title="5.指定匹配位置"></a>5.指定匹配位置</h3><blockquote><p>正则表达式的锚，将模式定位在搜索字符串的特定位置上</p></blockquote><table><thead><tr><th>字 符</th><th>含 义</th></tr></thead><tbody><tr><td><code>^</code></td><td>匹配字符串的开头，在多行检索中，匹配一行的开头</td></tr><tr><td><code>$</code></td><td>匹配字符串的结尾，在多行检索中，匹配一行的结尾</td></tr><tr><td><code>\b</code></td><td>匹配一个单词边界，简言之，就是位于字符\w和\W之间的位置，或位于字符\w和字符串的开头或结尾之间的位置(需要注意:[\b]匹配的是退格符)</td></tr><tr><td><code>\B</code></td><td>匹配非单词边界的位置</td></tr></tbody></table><ul><li>例:<ul><li><code>/^JavaScript$/</code>:匹配”JavaScript”单词</li><li><code>/\B[Ss]cript/</code>:与”JavaScript”和”/postscript”匹配，但不与”script”与”Script”.</li></ul></li></ul><h1 id="（三）常用的正则表达式"><a href="#（三）常用的正则表达式" class="headerlink" title="（三）常用的正则表达式"></a>（三）常用的正则表达式</h1><p>以下内容转载自：<a href="http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html" target="_blank" rel="noopener">http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html</a></p><h2 id="一、校验数字的表达式"><a href="#一、校验数字的表达式" class="headerlink" title="一、校验数字的表达式"></a>一、校验数字的表达式</h2><ol><li>数字：<code>^[0-9]*$</code></li><li>n位的数字：<code>^\d{n}$</code></li><li>至少n位的数字：<code>^\d{n,}$</code></li><li>m-n位的数字：<code>^\d{m,n}$</code></li><li>零和非零开头的数字：<code>^(0|[1-9][0-9]*)$</code></li><li>非零开头的最多带两位小数的数字：<code>^([1-9][0-9]*)+(.[0-9]{1,2})?$</code></li><li>带1-2位小数的正数或负数：<code>^(\-)?\d+(\.\d{1,2})?$</code></li><li>正数、负数、和小数：<code>^(\-|\+)?\d+(\.\d+)?$</code></li><li>有两位小数的正实数：<code>^[0-9]+(.[0-9]{2})?$</code></li><li>有1~3位小数的正实数：<code>^[0-9]+(.[0-9]{1,3})?$</code></li><li>非零的正整数：<code>^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$</code></li><li>非零的负整数：<code>^\-[1-9][]0-9&quot;*$ 或 ^-[1-9]\d*$</code></li><li>非负整数：<code>^\d+$ 或 ^[1-9]\d*|0$</code></li><li>非正整数：<code>^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$</code></li><li>非负浮点数：<code>^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$</code></li><li>非正浮点数：<code>^((-\d+(\.\d+)?)|(0+(\.0+)?))$</code> 或 <code>^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$</code></li><li>正浮点数：<code>^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$</code> 或 <code>^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$</code></li><li>负浮点数：<code>^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$</code> 或 <code>^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$</code></li><li>浮点数：<code>^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$</code></li></ol><h2 id="二、校验字符的表达式"><a href="#二、校验字符的表达式" class="headerlink" title="二、校验字符的表达式"></a>二、校验字符的表达式</h2><ol><li>汉字：<code>^[\u4e00-\u9fa5]{0,}$</code></li><li>英文和数字：<code>^[A-Za-z0-9]+$</code> 或 <code>^[A-Za-z0-9]{4,40}$</code></li><li>长度为3-20的所有字符：<code>^.{3,20}$</code></li><li>由26个英文字母组成的字符串：<code>^[A-Za-z]+$</code></li><li>由26个大写英文字母组成的字符串：<code>^[A-Z]+$</code></li><li>由26个小写英文字母组成的字符串：<code>^[a-z]+$</code></li><li>由数字和26个英文字母组成的字符串：<code>^[A-Za-z0-9]+$</code></li><li>由数字、26个英文字母或者下划线组成的字符串：<code>^\w+$</code> 或 <code>^\w{3,20}$</code></li><li>中文、英文、数字包括下划线：<code>^[\u4E00-\u9FA5A-Za-z0-9_]+$</code></li><li>中文、英文、数字但不包括下划线等符号：<code>^[\u4E00-\u9FA5A-Za-z0-9]+$</code> 或 <code>^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$</code></li><li>可以输入含有^%&amp;’,;=?$\”等字符：<code>[^%&amp;&#39;,;=?$\x22]+</code></li><li>禁止输入含有~的字符：<code>[^~\x22]+</code></li></ol><h2 id="三、特殊需求表达式"><a href="#三、特殊需求表达式" class="headerlink" title="三、特殊需求表达式"></a>三、特殊需求表达式</h2><ol><li><p>Email地址：<code>^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$</code></p></li><li><p>域名：<code>[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?</code></p></li><li>InternetURL：<code>[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&amp;=]*)?$</code></li><li>手机号码：<code>^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$</code></li><li>电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX)：<code>^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$</code></li><li>国内电话号码(0511-4405222、021-87888822)：<code>\d{3}-\d{8}|\d{4}-\d{7}</code></li><li>身份证号(15位、18位数字)：<code>^\d{15}|\d{18}$</code></li><li>短身份证号码(数字、字母x结尾)：<code>^([0-9]){7,18}(x|X)?$</code> 或 <code>^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$</code></li><li>帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：<code>^[a-zA-Z][a-zA-Z0-9_]{4,15}$</code></li><li>密码(以字母开头，长度在6~18之间，只能包含字母、数字和下划线)：<code>^[a-zA-Z]\w{5,17}$</code></li><li>强密码(必须包含大小写字母和数字的组合，不能使用特殊字符，长度在8-10之间)：<code>^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$</code>  </li><li>日期格式：<code>^\d{4}-\d{1,2}-\d{1,2}</code></li><li>一年的12个月(01～09和1～12)：<code>^(0?[1-9]|1[0-2])$</code></li><li>一个月的31天(01～09和1～31)：<code>^((0?[1-9])|((1|2)[0-9])|30|31)$</code></li><li><p>钱的输入格式：</p><ul><li>有四种钱的表示形式我们可以接受:”10000.00” 和 “10,000.00”, 和没有 “分” 的 “10000” 和 “10,000”：<code>^[1-9][0-9]*$</code></li><li>这表示任意一个不以0开头的数字,但是,这也意味着一个字符”0”不通过,所以我们采用下面的形式：<code>^(0|[1-9][0-9]*)$</code></li><li>一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号：<code>^(0|-?[1-9][0-9]*)$</code></li><li>这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分：<code>^[0-9]+(.[0-9]+)?$</code></li><li>必须说明的是,小数点后面至少应该有1位数,所以”10.”是不通过的,但是 “10” 和 “10.2” 是通过的：<code>^[0-9]+(.[0-9]{2})?$</code></li><li>这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样：<code>^[0-9]+(.[0-9]{1,2})?$</code></li><li>这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样：<code>^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$</code></li><li>1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须：<code>^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$</code></li></ul><p>备注：这就是最终结果了,别忘了”+”可以用”* “替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里</p></li><li><p>xml文件：<code>^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$</code></p></li><li>中文字符的正则表达式：<code>[\u4e00-\u9fa5]</code></li><li>双字节字符：<code>[^\x00-\xff]</code>    (包括汉字在内，可以用来计算字符串的长度(一个双字节字符长度计2，ASCII字符计1))</li><li>空白行的正则表达式：<code>\n\s*\r</code>    (可以用来删除空白行)</li><li>HTML标记的正则表达式：<code>&lt;(\S*?)[^&gt;]*&gt;.*?&lt;/\1&gt;|&lt;.*? /&gt;</code>    (网上流传的版本太糟糕，上面这个也仅仅能部分，对于复杂的嵌套标记依旧无能为力)</li><li>首尾空白字符的正则表达式：<code>^\s*|\s*$或(^\s*)|(\s*$)</code>    (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式)</li><li>腾讯QQ号：<code>[1-9][0-9]{4,}</code>    (腾讯QQ号从10000开始)</li><li>中国邮政编码：<code>[1-9]\d{5}(?!\d)</code>    (中国邮政编码为6位数字)</li><li>IP地址：<code>\d+\.\d+\.\d+\.\d+</code>    (提取IP地址时有用)</li><li>IP地址：<code>((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))</code></li></ol><h1 id="（四）参考资料"><a href="#（四）参考资料" class="headerlink" title="（四）参考资料"></a>（四）参考资料</h1><p><a href="http://www.ituring.com.cn/book/946" target="_blank" rel="noopener">JavaScript高级程序设计</a><br><a href="http://blog.guowenfh.com/2015/12/01/Regexp-basis/" target="_blank" rel="noopener">正则表达式-理论基础篇</a><br><a href="http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html" target="_blank" rel="noopener">最全的常用正则表达式大全</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;前端会遇到很多字符串验证问题，正则表达式是一个强大的字符串匹配工具，今天就来总结一下正则表达式。&lt;/p&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="https://baoyuzhang.github.io/categories/JavaScript/"/>
    
    
      <category term="正则表达式" scheme="https://baoyuzhang.github.io/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
    
  </entry>
  
  <entry>
    <title>【Hexo搭建独立博客全纪录】（三）使用Hexo搭建博客</title>
    <link href="https://baoyuzhang.github.io/2017/05/12/%E3%80%90Hexo%E6%90%AD%E5%BB%BA%E7%8B%AC%E7%AB%8B%E5%8D%9A%E5%AE%A2%E5%85%A8%E7%BA%AA%E5%BD%95%E3%80%91%EF%BC%88%E4%B8%89%EF%BC%89%E4%BD%BF%E7%94%A8Hexo%E6%90%AD%E5%BB%BA%E5%8D%9A%E5%AE%A2/"/>
    <id>https://baoyuzhang.github.io/2017/05/12/【Hexo搭建独立博客全纪录】（三）使用Hexo搭建博客/</id>
    <published>2017-05-12T01:54:06.000Z</published>
    <updated>2019-11-19T09:59:37.219Z</updated>
    
    <content type="html"><![CDATA[<p>每周一篇的频率更新博客，今天【Hexo搭建独立博客全纪录】系列终于进入正题：使用Hexo搭建博客，我搭建博客是跟着网上的教程一步一步做的，在此基础上结合官方文档，构成本文的内容。</p><a id="more"></a><p>参考资料：</p><ul><li>使用hexo+github搭建免费个人博客详细教程-liuxianan：<a href="http://blog.liuxianan.com/build-blog-website-by-hexo-github.html" target="_blank" rel="noopener">http://blog.liuxianan.com/build-blog-website-by-hexo-github.html</a></li><li>Hexo官方使用文档：<a href="https://hexo.io/zh-cn/docs/" target="_blank" rel="noopener">https://hexo.io/zh-cn/docs/</a></li><li>NexT 官方使用文档：<a href="http://theme-next.iissnan.com/" target="_blank" rel="noopener">http://theme-next.iissnan.com/</a></li></ul><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>使用github pages服务搭建博客的好处有：</p><ol><li>全是静态文件，访问速度快；</li><li>免费方便，不用花一分钱就可以搭建一个自由的个人博客，不需要服务器不需要后台；</li><li>可以随意绑定自己的域名，不仔细看的话根本看不出来你的网站是基于github的；</li><li>数据绝对安全，基于github的版本管理，想恢复到哪个历史版本都行；</li><li>博客内容可以轻松打包、转移、发布到其它平台；</li><li>等等；</li></ol><h1 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h1><p>在开始一切之前，你必须已经：</p><ul><li>有一个github账号，没有的话去注册一个；</li><li>安装了node.js、npm，并了解相关基础知识；</li><li>安装了git for windows（或者其它git客户端），安装过程在<a href="https://baoyuzhang.github.io/2017/04/28/%E3%80%90Hexo%E6%90%AD%E5%BB%BA%E7%8B%AC%E7%AB%8B%E5%8D%9A%E5%AE%A2%E5%85%A8%E7%BA%AA%E5%BD%95%E3%80%91%EF%BC%88%E4%B8%80%EF%BC%89%E4%BD%BF%E7%94%A8Git%E5%92%8CGithub/">【Hexo搭建独立博客全纪录】（一）使用Git和Github</a>中已讲过</li></ul><p>本文所使用的环境：</p><ul><li>Windows7</li><li><a href="mailto:node.js@6.9.4" target="_blank" rel="noopener">node.js@6.9.4</a> —— git命令行输入<code>node -v</code></li><li><a href="mailto:git@2.8.1.windows.1" target="_blank" rel="noopener">git@2.8.1.windows.1</a> —— git命令行输入<code>git version</code></li><li><a href="mailto:hexo@3.3.1" target="_blank" rel="noopener">hexo@3.3.1</a> —— git命令行输入<code>hexo -v</code>或<code>hexo version</code></li></ul><h1 id="搭建github博客"><a href="#搭建github博客" class="headerlink" title="搭建github博客"></a>搭建github博客</h1><h2 id="创建仓库"><a href="#创建仓库" class="headerlink" title="创建仓库"></a>创建仓库</h2><p>新建一个名为<code>你的用户名.github.io</code>的仓库，比如说，如果你的github用户名是test，那么你就新建<code>test.github.io</code>的仓库（必须是你的用户名，其它名称无效），将来你的网站访问地址就是 <a href="http://test.github.io" target="_blank" rel="noopener">http://test.github.io</a> 了，是不是很方便？</p><p>由此可见，每一个github账户最多只能创建一个这样可以直接使用域名访问的仓库。</p><p>几个注意的地方：</p><ol><li>注册的邮箱一定要验证，否则不会成功；</li><li>仓库名字必须是：<code>username.github.io</code>，其中<code>username</code>是你的用户名；</li></ol><p>创建成功后，以后你的博客所有代码都是放在这个仓库里啦。</p><h2 id="配置SSH-key（配置过的请跳过）"><a href="#配置SSH-key（配置过的请跳过）" class="headerlink" title="配置SSH key（配置过的请跳过）"></a>配置SSH key（配置过的请跳过）</h2><p>这一步骤在<a href="https://baoyuzhang.github.io/2017/04/28/%E3%80%90Hexo%E6%90%AD%E5%BB%BA%E7%8B%AC%E7%AB%8B%E5%8D%9A%E5%AE%A2%E5%85%A8%E7%BA%AA%E5%BD%95%E3%80%91%EF%BC%88%E4%B8%80%EF%BC%89%E4%BD%BF%E7%94%A8Git%E5%92%8CGithub/">【Hexo搭建独立博客全纪录】（一）使用Git和Github</a>4.1和4.2中也已讲过，如果在前面已经配置过SSH key，则可以跳过此步骤。</p><p>为什么要配置这个呢？因为你提交代码肯定要拥有你的github权限才可以，但是直接使用用户名和密码太不安全了，所以我们使用ssh key来解决本地和服务器的连接问题。</p><h3 id="创建SSH-Key"><a href="#创建SSH-Key" class="headerlink" title="创建SSH Key"></a>创建SSH Key</h3><p>查看是否已经有ssh密钥：<br>打开用户主目录”C:\Users\Administrator.hp-PC”，<br>看看有没有.ssh目录。</p><ul><li>如果有，再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件。如果有，可以直接跳至下一小节“Github中添加SSH Key”</li><li>如果已经有ssh密钥，想要重新生成ssh密钥，需要清理原有ssh密钥：<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir key_backup</span><br><span class="line">$ cp id_rsa* key_backup</span><br><span class="line">$ rm id_rsa*</span><br></pre></td></tr></table></figure></li><li><p>如果没有，打开命令行，输入命令<code>ssh-keygen  -t rsa –C “youremail@example.com”</code>。此处的邮箱地址，你可以输入自己的邮箱地址。在回车中会提示你输入一个密码，这个密码会在你提交项目时使用，如果为空的话提交项目时则不用输入。这个设置是防止别人往你的项目里提交内容。</p><p>由于我本地此前运行过一次，所以本地有，如下所示：</p></li></ul><p><img src="/img/2017-04-29_153448.png" alt="&quot;.ssh&quot;"></p><p>id_rsa是私钥，不能泄露出去，id_rsa.pub是公钥，可以放心地告诉任何人。由于之前使用Github客户端，因此还有github_rsa和github_rsa.pub两个文件。known_hosts文件如果没有暂时不管。</p><p>验证是否连接成功，连接成功显示<code>Hi baoyuzhang! You&#39;ve successfully authenticated, but GitHub does not provide shell access.</code>。如下：<br><img src="/img/2017-04-29_160356.png" alt="&quot;验证是否连接成功&quot;"></p><h3 id="Github中添加SSH-Key"><a href="#Github中添加SSH-Key" class="headerlink" title="Github中添加SSH Key"></a>Github中添加SSH Key</h3><p>登录github，点击个人头像打开”settings”，再打开”SSH and GPG keys”页面，然后点击”New SSH Key”，填上任意title，在”Key”文本框里黏贴id_rsa.pub文件的内容，点击 Add Key，你就应该可以看到已经添加的key。如下：<br><img src="/img/2017-04-29_155435.png" alt="&quot;Github中添加SSH Key&quot;"></p><h1 id="使用hexo博客框架"><a href="#使用hexo博客框架" class="headerlink" title="使用hexo博客框架"></a>使用hexo博客框架</h1><p>Hexo官方使用文档：<a href="https://hexo.io/zh-cn/docs/" target="_blank" rel="noopener">https://hexo.io/zh-cn/docs/</a></p><p>本文使用的命令和官方文档不太一样，但意思相同，达到的效果也相同。初学者建议跟着本文一步一不做。</p><h2 id="hexo简介"><a href="#hexo简介" class="headerlink" title="hexo简介"></a>hexo简介</h2><h3 id="a-hexo是什么"><a href="#a-hexo是什么" class="headerlink" title="a.hexo是什么"></a>a.hexo是什么</h3><p>Hexo是一个简单、快速、强大的基于 Github Pages 的博客框架，支持Markdown格式，有众多优秀插件和主题。</p><p>github: <a href="https://github.com/hexojs/hexo" target="_blank" rel="noopener">https://github.com/hexojs/hexo</a></p><p>Hexo中文官网： <a href="https://hexo.io/zh-cn/" target="_blank" rel="noopener">https://hexo.io/zh-cn/</a></p><h3 id="b-hexo原理"><a href="#b-hexo原理" class="headerlink" title="b.hexo原理"></a>b.hexo原理</h3><p>由于github pages存放的都是静态文件，博客存放的不只是文章内容，还有文章列表、分类、标签、翻页等动态内容，假如每次写完一篇文章都要手动更新博文目录和相关链接信息，相信谁都会疯掉，所以hexo所做的就是将这些md文件都放在本地，每次写完文章后调用写好的命令来批量完成相关页面的生成，然后再将有改动的页面提交到github。</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="a-注意事项"><a href="#a-注意事项" class="headerlink" title="a.注意事项"></a>a.注意事项</h3><p>安装之前先来说几个注意事项：</p><ol><li>很多命令既可以用Windows的cmd来完成，也可以使用git bash来完成，但是部分命令会有一些问题，为避免不必要的问题，建议全部使用git bash来执行；</li><li>hexo不同版本差别比较大，网上很多文章的配置信息都是基于2.x的，所以注意不要被误导；</li><li>hexo有2种<code>_config.yml</code>文件，一个是根目录下的全局的<code>_config.yml</code>，一个是各个<code>theme</code>下的<code>_config.yml</code>。为了描述方便，在以下说明中，将前者称为 <strong>站点配置文件</strong>， 后者称为 <strong>主题配置文件</strong>。</li></ol><h3 id="b-安装Hexo"><a href="#b-安装Hexo" class="headerlink" title="b.安装Hexo"></a>b.安装Hexo</h3><p>在git bush输入以下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g hexo</span><br></pre></td></tr></table></figure><h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2><h3 id="a-初始化"><a href="#a-初始化" class="headerlink" title="a.初始化"></a>a.初始化</h3><p>在电脑的某个地方新建一个名为hexo的文件夹（名字可以随便取），比如我的是<code>E:\web\github\test\hexo</code>，由于这个文件夹将来就作为你存放博客代码的地方，所以最好不要随便放。</p><p><img src="/img/2017-05-12_132624.png" alt=""><br>hexo会自动下载一些文件到这个目录，包括node_modules，目录结构如下图：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── _config.yml</span><br><span class="line">├── package.json</span><br><span class="line">├── scaffolds</span><br><span class="line">├── source</span><br><span class="line">|   ├── _drafts</span><br><span class="line">|   └── _posts</span><br><span class="line">└── themes</span><br></pre></td></tr></table></figure></p><p><img src="/img/2017-05-12_132732.png" alt=""></p><h3 id="b-生成静态文件"><a href="#b-生成静态文件" class="headerlink" title="b.生成静态文件"></a>b.生成静态文件</h3><p><img src="/img/2017-05-12_134450.png" alt=""></p><p>执行以上命令之后，hexo就会在public文件夹生成相关html文件，这些文件将来都是要提交到github上<code>你的用户名.github.io</code>的仓库上去的：</p><p><img src="/img/2017-05-12_134606.png" alt=""></p><h3 id="c-本地预览"><a href="#c-本地预览" class="headerlink" title="c.本地预览"></a>c.本地预览</h3><p><code>hexo s</code>是开启本地预览服务，打开浏览器访问 <a href="http://localhost:4000" target="_blank" rel="noopener">http://localhost:4000</a> 即可看到内容，<code>Ctrl+C</code>停止本地预览。</p><p><img src="/img/2017-05-12_134936.png" alt=""></p><p>若浏览器一直在转圈但是就是加载不出来，或执行<code>hexo s</code>命令出现以下提示：</p><p><img src="/img/2017-05-12_135326.png" alt=""></p><p>这一般情况下是因为4000端口占用的缘故，因为4000这个端口太常见了，解决端口冲突问题请参考这篇文章：</p><p><a href="http://blog.liuxianan.com/windows-port-bind.html" target="_blank" rel="noopener">http://blog.liuxianan.com/windows-port-bind.html</a></p><p>第一次初始化的时候hexo已经帮我们写了一篇名为 Hello World 的文章，默认的主题比较丑，打开时就是这个样子：</p><p><img src="/img/2017-05-12_135425.png" alt=""></p><h2 id="更改主题"><a href="#更改主题" class="headerlink" title="更改主题"></a>更改主题</h2><p>既然默认主题很丑，那我们别的不做，首先来替换一个好看点的主题。</p><ul><li><p><a href="https://hexo.io/themes/" target="_blank" rel="noopener">官方主题</a>：官方提供的各种主题</p></li><li><p><a href="https://www.zhihu.com/question/24422335" target="_blank" rel="noopener">有哪些好看的 Hexo 主题? - 知乎</a></p></li></ul><p>这里我推荐使用使用量排名第一的主题NexT。更换NexT主题可以参考<a href="http://theme-next.iissnan.com/" target="_blank" rel="noopener">NexT 官方使用文档</a>，点击<code>开始使用</code>一步一步操作。下面做一个示范，并且下周写的优化设置的文章，也是基于NexT主题，可以跟着我一步一步来做。</p><h3 id="a-下载主题"><a href="#a-下载主题" class="headerlink" title="a.下载主题"></a>a.下载主题</h3><p><img src="/img/2017-05-12_163723.png" alt=""></p><h3 id="b-启用主题"><a href="#b-启用主题" class="headerlink" title="b.启用主题"></a>b.启用主题</h3><p>打开根目录下<strong>站点配置文件</strong><code>_config.yml</code>， 找到 theme 字段，并将其值更改为 next。</p><p><img src="/img/2017-05-12_164701.png" alt=""></p><p>到此，NexT 主题安装完成。下一步我们将验证主题是否正确启用。</p><h3 id="c-验证主题"><a href="#c-验证主题" class="headerlink" title="c.验证主题"></a>c.验证主题</h3><p>在切换主题之后、验证之前， 我们最好使用 hexo clean 来清除 Hexo 的缓存，以免出现一些莫名其妙的问题。然后重新执行<code>hexo g</code>来重新生成。</p><p><img src="/img/2017-05-12_165136.png" alt=""></p><p><img src="/img/2017-05-12_165228.png" alt=""></p><p>使用<code>hexo s</code>本地预览，如果你的博客变为下图的样子，则安装NexT主题成功：</p><p><img src="/img/2017-05-12_165315.png" alt=""></p><h2 id="上传到github"><a href="#上传到github" class="headerlink" title="上传到github"></a>上传到github</h2><h3 id="a-配置站点配置文件"><a href="#a-配置站点配置文件" class="headerlink" title="a.配置站点配置文件"></a>a.配置站点配置文件</h3><p>打开根目录下<strong>站点配置文件</strong><code>_config.yml</code>，配置有关deploy的部分：</p><p><img src="/img/2017-05-12_170337.png" alt=""></p><h3 id="b-安装插件"><a href="#b-安装插件" class="headerlink" title="b.安装插件"></a>b.安装插件</h3><p>此时，直接使用<code>hexo d</code>部署到github，将出现如下错误：</p><p><img src="/img/2017-05-12_170608.png" alt=""></p><p>这是因为需要安装如下插件：</p><p><img src="/img/2017-05-12_171236.png" alt=""></p><h3 id="c-部署到github"><a href="#c-部署到github" class="headerlink" title="c.部署到github"></a>c.部署到github</h3><p>其它命令不确定，<code>hexo d</code>部署这个命令一定要用git bash，否则会提示Permission denied (publickey).</p><p><img src="/img/2017-05-12_171708.png" alt=""></p><p>中间好长的安装过程，然后安装成功：</p><p><img src="/img/2017-05-12_171748.png" alt=""></p><p>这时，打开<code>https://你的用户名.github.io/</code>，出现下图，则表示部署到github成功：</p><p><img src="/img/2017-05-12_172010.png" alt=""></p><p>再打开github仓库，已经有了内容：</p><p><img src="/img/2017-05-12_215445.png" alt=""></p><h2 id="基本配置"><a href="#基本配置" class="headerlink" title="基本配置"></a>基本配置</h2><p>我们自己的博客出现Hello World并不是我们想要的，那么我们来进一步配置，将它真正我们自己的博客。</p><p>打开根目录下<strong>站点配置文件</strong><code>_config.yml</code>，设置如下内容：</p><p><img src="/img/2017-05-12_172848.png" alt=""></p><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>title</td><td>网站标题</td></tr><tr><td>subtitle</td><td>网站副标题</td></tr><tr><td>description</td><td>网站描述</td></tr><tr><td>author</td><td>您的名字</td></tr><tr><td>language</td><td>网站使用的语言</td></tr><tr><td>timezone</td><td>网站时区。Hexo 默认使用您电脑的时区。</td></tr></tbody></table><p>其中，description主要用于SEO，告诉搜索引擎一个关于您站点的简单描述，通常建议在其中包含您网站的关键词。author参数用于主题显示文章的作者。</p><p>配置完成后，重新部署，会发现如下变化：</p><p><img src="/img/2017-05-12_173441.png" alt=""></p><p>但文章内容还不是我们自己的呀，下面来写我们自己的博客。</p><h2 id="写博客"><a href="#写博客" class="headerlink" title="写博客"></a>写博客</h2><h3 id="新建文章"><a href="#新建文章" class="headerlink" title="新建文章"></a>新建文章</h3><p>执行<code>hexo new &#39;文章名&#39;</code>，hexo会帮我们在<code>..\hexo\source\_posts</code>下生成相关md文件：<br><img src="/img/2017-05-12_173830.png" alt=""></p><p>打开这个文件就可以开始写博客了，默认生成如下内容：</p><p><img src="/img/2017-05-12_174254.png" alt=""></p><p>当然你也可以直接自己新建md文件，用这个命令的好处是帮我们自动生成了时间。一般完整格式如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: postName #文章页面上的显示名称，一般是中文</span><br><span class="line">date: 2013-12-02 15:30:16 #文章生成时间，一般不改，当然也可以任意修改</span><br><span class="line">categories: 默认分类 #分类</span><br><span class="line">tags: [tag1,tag2,tag3] #文章标签，可空，多标签请用格式，注意:后面有个空格</span><br><span class="line">description: 附加一段文章摘要，字数最好在140字以内，会出现在meta的description里面</span><br><span class="line">---</span><br><span class="line"></span><br><span class="line">以下是正文</span><br></pre></td></tr></table></figure><p>删除<code>hello-world.md</code>，同时删除<code>public</code>文件夹下的<code>hello-world</code>文件夹：</p><p><img src="/img/2017-05-12_175327.png" alt=""></p><p>将编写好的文章保存，重新生成和部署就可以啦！</p><p><img src="/img/2017-05-12_175533.png" alt=""></p><h3 id="新建页面"><a href="#新建页面" class="headerlink" title="新建页面"></a>新建页面</h3><p>假如我新建一个名字为<code>about</code>的页面：</p><p><img src="/img/2017-05-12_212448.png" alt=""></p><p>在source文件夹下，将生成about文件夹：</p><p><img src="/img/2017-05-12_212816.png" alt=""></p><p>部署后将在public文件夹生成一个新的html页面：<code>hexo\public\about\index.html</code>，通过访问<code>https://用户名.github.io/about/</code>访问这个页面：</p><p><img src="/img/2017-05-12_213128.png" alt=""></p><p>你可以通过编辑<code>index.html</code>，添加自己的简历等其他你想加入的内容。但注意，它是新建了一个html页面，不是文章，不会出现在博文目录。</p><p>至此，博客的基本功能已经全部实现，下面的高级配置，让你更加方便快捷的写博客！</p><h2 id="高级配置"><a href="#高级配置" class="headerlink" title="高级配置"></a>高级配置</h2><p>现在，Hexo根目录结构如下图：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── _config.yml</span><br><span class="line">├── db.json</span><br><span class="line">├── package.json</span><br><span class="line">├── public</span><br><span class="line">├── scaffolds</span><br><span class="line">├── source</span><br><span class="line">|   ├── _drafts</span><br><span class="line">|   └── _posts</span><br><span class="line">└── themes</span><br></pre></td></tr></table></figure></p><p><img src="/img/2017-05-12_205535.png" alt=""></p><p>下面介绍的几个是会经常用到的：</p><h3 id="config-yml"><a href="#config-yml" class="headerlink" title="_config.yml"></a><code>_config.yml</code></h3><p>网站配置信息，也就是本文所称的<strong>站点配置文件</strong>，可以在此配置大部分的参数。基本配置在前面基本已经设置过了。</p><h3 id="scaffolds"><a href="#scaffolds" class="headerlink" title="scaffolds"></a>scaffolds</h3><p>模版文件夹。新建文章时，Hexo 会根据 scaffold 来建立文件。</p><p>Hexo的模板是指新建的markdown文件中默认填充的内容。例如，在使用<code>hexo new 文章名</code>时，默认生成的md文件会包含如下内容：</p><p><img src="/img/2017-05-12_210715.png" alt=""></p><p>默认内容是哪里来的呢？就在scaffold/post.md中保存：</p><p><img src="/img/2017-05-12_211000.png" alt=""></p><p>假如对每篇博客我都需要添加分类<code>categories</code>，每次都手动添加太麻烦，我希望每次默认生成都有<code>categories:</code>，那么就可以在scaffold/post.md中添加：</p><p><img src="/img/2017-05-12_211445.png" alt=""></p><p>保存后，每次新建一篇文章时都会包含post.md中的内容。</p><p>当然，你也可以在scaffolds文件夹下创建自己的博客模板，我创建一个名为<code>blog</code>的模板：</p><p><img src="/img/2017-05-12_214011.png" alt=""></p><p><img src="/img/2017-05-12_214203.png" alt=""></p><p>通过如下命令调用我创建的blog模板新建文章：</p><p><img src="/img/2017-05-12_214327.png" alt=""></p><p>在<code>_posts</code>中生成md文件：</p><p><img src="/img/2017-05-12_214449.png" alt=""></p><p><img src="/img/2017-05-12_214617.png" alt=""></p><h3 id="public"><a href="#public" class="headerlink" title="public"></a>public</h3><p>该文件夹中的内容将被最终push到github仓库中。</p><h3 id="source"><a href="#source" class="headerlink" title="source"></a>source</h3><p>资源文件夹是存放用户资源的地方。除<code>_posts</code> 文件夹之外，开头命名为 _ (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 public 文件夹，而其他文件（如刚刚生成的about文件夹）会被拷贝到 public 文件夹。</p><h4 id="为github仓库添加readme"><a href="#为github仓库添加readme" class="headerlink" title="为github仓库添加readme"></a>为github仓库添加readme</h4><p>既然 source 文件夹中的内容将全部被推送到 public 文件夹，public 文件夹中的内容又将被最终push到github仓库中，那么如果我们想要为github仓库添加readme.md，只要在 source 文件夹中创建就好了：</p><p><img src="/img/2017-05-12_220101.png" alt=""></p><p>部署到github，就有readme了，但我们发现，README.md已经被解析为README.html，显示的全是html代码，并不是我们想要的文档格式的内容：</p><p><img src="/img/2017-05-12_220428.png" alt=""></p><p>为了解决这个问题，我们回到source文件夹，将<code>README.md</code>重命名为<code>README.MDOWN</code>，再部署到github：</p><p><img src="/img/2017-05-12_220814.png" alt=""></p><p><img src="/img/2017-05-12_221120.png" alt=""></p><p>source文件夹中，.md会被解析为html，并放到 public 文件夹被push到github，但.MDWN不会被解析。</p><h3 id="themes"><a href="#themes" class="headerlink" title="themes"></a>themes</h3><p>主题文件夹，下载的主题都保存在此文件夹下。Hexo 会根据主题来生成静态页面。</p><p><img src="/img/2017-05-12_214937.png" alt=""></p><h2 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h2><p><a href="https://baoyutong.github.io/" target="_blank" rel="noopener">点击查看最终效果</a></p><p>搭的这个博客只是为了写这篇文章，我<a href="https://baoyuzhang.github.io/">真正的博客</a>在这里哟！</p><h1 id="Hexo常用命令"><a href="#Hexo常用命令" class="headerlink" title="Hexo常用命令"></a>Hexo常用命令</h1><p>常用命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">hexo new &quot;postName&quot; #新建文章</span><br><span class="line">hexo generate #生成静态页面至public目录</span><br><span class="line">hexo server #开启预览访问端口（默认端口4000，&apos;ctrl + c&apos;关闭server）</span><br><span class="line">hexo deploy #部署到GitHub</span><br><span class="line">hexo help  # 查看帮助</span><br><span class="line">hexo version  #查看Hexo的版本</span><br></pre></td></tr></table></figure><p>缩写：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">hexo n == hexo new</span><br><span class="line">hexo g == hexo generate</span><br><span class="line">hexo s == hexo server</span><br><span class="line">hexo d == hexo deploy</span><br></pre></td></tr></table></figure><p>组合命令：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hexo s -g #生成并本地预览</span><br><span class="line">hexo d -g #生成并上传</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;每周一篇的频率更新博客，今天【Hexo搭建独立博客全纪录】系列终于进入正题：使用Hexo搭建博客，我搭建博客是跟着网上的教程一步一步做的，在此基础上结合官方文档，构成本文的内容。&lt;/p&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="Github" scheme="https://baoyuzhang.github.io/tags/Github/"/>
    
      <category term="Hexo" scheme="https://baoyuzhang.github.io/tags/Hexo/"/>
    
  </entry>
  
  <entry>
    <title>【Hexo搭建独立博客全纪录】（二）使用Markdown</title>
    <link href="https://baoyuzhang.github.io/2017/05/05/%E3%80%90Hexo%E6%90%AD%E5%BB%BA%E7%8B%AC%E7%AB%8B%E5%8D%9A%E5%AE%A2%E5%85%A8%E7%BA%AA%E5%BD%95%E3%80%91%EF%BC%88%E4%BA%8C%EF%BC%89%E4%BD%BF%E7%94%A8Markdown/"/>
    <id>https://baoyuzhang.github.io/2017/05/05/【Hexo搭建独立博客全纪录】（二）使用Markdown/</id>
    <published>2017-05-05T01:48:33.000Z</published>
    <updated>2017-05-05T03:47:17.000Z</updated>
    
    <content type="html"><![CDATA[<p>Markdown 是一种轻量级的标记语言，其用简单的标记语法便可达到排版的目的，其可以使我们更加专注于内容的编写，而不需过多关注排版。本文主要整理了 Markdown 中的常用的标记语法，以便自己与他人以后查用。</p><p>Hexo是基于Github的博客平台，Github中的文本格式是.md，那么用Hexo写博客也必然要用到Markdown。本文首先带你选择适合你的Markdown编辑器(推荐Atom)，然后对Markdown语法做一简要介绍。</p><a id="more"></a><h2 id="Markdown编辑器"><a href="#Markdown编辑器" class="headerlink" title="Markdown编辑器"></a>Markdown编辑器</h2><p>支持Markdown的编辑器有好多，功能也不完全一致，有的是用来进行基本的写作，有的是用来写代码的，有的甚至只是博客平台配套的编辑器。想了解<a href="http://www.williamlong.info/archives/4319.html" target="_blank" rel="noopener">好用的Markdown编辑器</a>，可以点开链接。</p><p>根据我个人的需求，我使用Atom作为本地Markdown编辑器，使用<a href="http://www.jianshu.com/u/fef0cc2349a1" target="_blank" rel="noopener">简书</a>发布文章，与我的博客同步更新。这里要安利一波Atom！</p><h3 id="Atom-介绍"><a href="#Atom-介绍" class="headerlink" title="Atom 介绍"></a>Atom 介绍</h3><p><a href="https://atom.io/" target="_blank" rel="noopener">Atom</a>，Github出的编辑器，支持各种编程语言，拥有和Sublime类似的丰富插件，同时结合了Markdown本地预览功能，打开github仓库还能显示各文件的状态。除此之外，颜值还高啊！默认高亮就很好看，深深吸引了颜控的我。Atom简直就是一款取代Sublime的神器！总而言之，作为一个前端程序员，日常的敲代码，用Git和Github版本控制，Markdown写博客，有Atom就够了！</p><p>Atom预览Markdown快捷键：Ctrl+Shift+M</p><p>关于Atom的用法，不属于本文内容，这里只附上链接：</p><ul><li><a href="https://github.com/CompileYouth/front-end-study/blob/master/tool/atom/%E7%A3%A8%E5%88%80%E4%B8%8D%E8%AF%AF%E7%A0%8D%E6%9F%B4%E5%B7%A5%EF%BC%9AAtom%20%E4%BB%8B%E7%BB%8D.md" target="_blank" rel="noopener">Atom 介绍</a></li><li><a href="https://atom-china.org/t/atom/62" target="_blank" rel="noopener">Atom基础使用</a></li><li><a href="https://npm.taobao.org/mirrors/atom" target="_blank" rel="noopener">Atom 安装包国内镜像</a></li><li><a href="https://atom-china.org/t/faq/326" target="_blank" rel="noopener">FAQ、官方博客/手册索引、插件推荐专题</a></li></ul><h2 id="Markdown语法介绍"><a href="#Markdown语法介绍" class="headerlink" title="Markdown语法介绍"></a>Markdown语法介绍</h2><ul><li><a href="http://www.jianshu.com/p/q81RER#" target="_blank" rel="noopener">献给写作者的 Markdown 新手指南</a>：必推的小白入门教程，跟着做一遍就可以上手写文章啦~</li><li><a href="http://wowubuntu.com/markdown/" target="_blank" rel="noopener">Markdown 语法说明(简体中文版)</a>：进阶教程，分为快速入门和完整语法说明两版，给web开发者的Markdown教程，需要有HTML基础</li><li><a href="https://github.com/CompileYouth/front-end-study/blob/master/tool/markdown/Markdown-Learning.md" target="_blank" rel="noopener">本文的Markdown语法介绍</a></li></ul><h3 id="段落元素"><a href="#段落元素" class="headerlink" title="段落元素"></a>段落元素</h3><h4 id="1、段落与换行"><a href="#1、段落与换行" class="headerlink" title="1、段落与换行"></a>1、段落与换行</h4><p>Markdown 中的段落指连续的一段文字，编写时段落之间用至少一个<strong>空行</strong>隔开，段落内多个空格将被视为一个空格，段首不支持缩进。</p><p>如果想要在显示时显示多个空行，可以插入 <code>&lt;br/&gt;</code> 来实现，注意的是，插入的 <code>&lt;br/&gt;</code> 应与前后的段落中间至少空一行。</p><h4 id="2、标题"><a href="#2、标题" class="headerlink" title="2、标题"></a>2、标题</h4><p>Markdown 支持两种类型的标题。</p><pre><code>//类型 1这是一级标题==========这是二级标题----------//类型 2# 这是一级标题## 这是二级标题...###### 这是六级标题</code></pre><p>从上面可以看出类型 1 是在标题下面插入 <code>=</code> 或者 <code>-</code> 来标识标题等级，但局限是其只能表示两个级别的标题。</p><p>类型 2 是在标题前面插入 1 - 6 个 # ，表示 6 个等级的标题，这是比较推荐的用法。</p><h4 id="3、引用"><a href="#3、引用" class="headerlink" title="3、引用"></a>3、引用</h4><p>Markdown 中使用 <code>&gt;</code> 来引用。我们可以在一段文字中的每行开头加上 <code>&gt;</code> 来表示一段引用文字，也可以只在一段文字的开头插入一个 <code>&gt;</code> 来表示，如下面的 1、2 两种方式：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">//方式 1</span><br><span class="line">&gt; 这是一句话</span><br><span class="line">&gt; 这是第二句话</span><br><span class="line"></span><br><span class="line">//方式 2</span><br><span class="line">&gt; 这是一句话</span><br><span class="line">这是第二句话</span><br></pre></td></tr></table></figure><p>Markdown 支持使用不同数量的 <code>&gt;</code> 表示嵌套引用。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt; 这是外层的引用</span><br><span class="line">&gt; &gt; 这是内层的引用</span><br></pre></td></tr></table></figure><h4 id="4、无序列表"><a href="#4、无序列表" class="headerlink" title="4、无序列表"></a>4、无序列表</h4><p>无序列表使用 <code>-</code>、 <code>+</code> 或 <code>*</code> 来作为标记。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">- 第一项</span><br><span class="line">- 第二项</span><br><span class="line">- 第三项</span><br></pre></td></tr></table></figure><p>上面的 <code>-</code> 可以用 <code>+</code>、 <code>*</code>替换。需要注意的是，<code>-</code> 等符号与后面的文字至少空一格空格。</p><h4 id="5、有序列表"><a href="#5、有序列表" class="headerlink" title="5、有序列表"></a>5、有序列表</h4><p>有序列表使用数字和紧挨着的点号表示。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. 第一项</span><br><span class="line">2. 第二项</span><br><span class="line">3. 第三项</span><br></pre></td></tr></table></figure><p>同无序列表一样，标记符号与后面的文字至少空一格空格。但编辑时的数字对显示无影响。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">2. 第一项</span><br><span class="line">6. 第二项</span><br><span class="line">1. 第三项</span><br></pre></td></tr></table></figure><p>上面的例子与前一个显示的结果完全一致，但建议编辑时按照数字顺序。</p><h5 id="列表"><a href="#列表" class="headerlink" title="列表"></a>列表</h5><ul><li><p>有序列表和无序列表的每一项中均可嵌套其他列表；</p></li><li><p>在列表项之间要插入段落时，这时需要将列表项之间的段落缩进 4 个空格；</p></li><li><p>使用 <code>1\.</code> 来输出 <code>1.</code>;</p></li></ul><h4 id="6、代码区块"><a href="#6、代码区块" class="headerlink" title="6、代码区块"></a>6、代码区块</h4><p>缩进 4 个空格，需要注意的是，每行代码都需要至少缩进 4 个空格，不能像段落一样采用首行标记的偷懒写法，一个代码区会一直持续到没有缩进 4 个空格的那一行。</p><p>也可以用一对三个连续的撇号 <code>`</code> 来包裹代码段。</p><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">code</span><br></pre></td></tr></table></figure></code></pre><p>有的解释器还能根据代码的语言从而给代码加上语法高亮。</p><pre><code><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">func</span>(<span class="params"></span>) </span>&#123;&#125;</span><br></pre></td></tr></table></figure></code></pre><h4 id="7、分割线"><a href="#7、分割线" class="headerlink" title="7、分割线"></a>7、分割线</h4><p>使用三个及以上的 <code>*</code>、 <code>-</code> 或 <code>_</code>来表示一个分割线，符号不能混用，符号之间可以插入多个空格。需要注意的是，使用 <code>-</code> 来插入分割线时需要与上一个段落至少空一行，否则 Markdown 会将上一行文字解释为二级标题。</p><h4 id="8、表格"><a href="#8、表格" class="headerlink" title="8、表格"></a>8、表格</h4><p>表格是 Markdown 比较复杂的一种表示。</p><pre><code>| Table | Col1 | Col2 || ----- |:----:| ----:|| Row1  | 1-1  | 1-2  || Row2  | 2-1  | 2-2  || Row3  | 3-1  | 3-2  |</code></pre><p>上面第二行中的点代表对齐方式，分别是默认（居右）、居中、居左。</p><hr><h3 id="行内元素"><a href="#行内元素" class="headerlink" title="行内元素"></a>行内元素</h3><h4 id="9、超链接"><a href="#9、超链接" class="headerlink" title="9、超链接"></a>9、超链接</h4><p>Markdown 中有三种方式实现超链接。</p><pre><code>//方式 1[百度](http://www.baidu.com)//方式 2[百度][Baidu-url][Baidu-url]: http://www.baidu.com</code></pre><p>方式 1 较为常用，也可以为链接的文字加上提示文字，只要在括号中超链接加上空格后添加提示内容即可。</p><pre><code>[百度](http://www.baidu.com &quot;这是提示文字&quot;)</code></pre><p>方式 2 由链接文字和链接地址组成，不同的是两者均由 <code>[]</code> 包裹。链接地址的格式为：</p><ul><li>方括号，里面输入链接地址；</li><li>紧接着是一个冒号；</li><li>冒号后面至少一个空格；</li><li>链接地址；</li><li>若有提示文字，空格后用引号或者括号包裹提示文字。</li></ul><p>下面是完整示例：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[百度][Baidu-url]</span><br><span class="line">[Baidu-url]: http://www.baidu.com &quot;这是提示文字&quot;</span><br></pre></td></tr></table></figure><p>第三种方式是用 <code>&lt;&gt;</code> 来包裹 URL。</p><pre><code>//方式 3&lt;http://www.baidu.com&gt;</code></pre><h4 id="10、加粗和斜体"><a href="#10、加粗和斜体" class="headerlink" title="10、加粗和斜体"></a>10、加粗和斜体</h4><p>Markdown 使用 <code>*</code> 和 <code>_</code> 来表示粗体和斜体。</p><pre><code>//加粗**这是加粗文字**__这也是加粗文字__//斜体*这是斜体文字*_这也是斜体文字_</code></pre><p>被偶数个 <code>*</code> 或 <code>_</code> 包裹的文字显示加粗效果，被奇数个包裹的为倾斜效果。</p><p>需要注意的是，<code>*</code> 和 <code>-</code> 要成对出现，不能混合使用，也不能只出现一个。同时，标识符号要与标识的文字紧挨着，符号与符号之间、符号文字之间不能有任何空格。</p><h4 id="11、代码"><a href="#11、代码" class="headerlink" title="11、代码"></a>11、代码</h4><p>使用 <code>`</code> (撇号) 来包裹一小段代码。</p><pre><code>`Hello world.`</code></pre><p>若想在代码中添加撇号，可以使用多个撇号包裹里面需要添加的撇号，但注意里面的连续的撇号数量不能超过外面的数量。</p><pre><code>//显示一个撇号`` ` ``</code></pre><h4 id="12、图片"><a href="#12、图片" class="headerlink" title="12、图片"></a>12、图片</h4><p>图片的插入方式跟超链接前两种插入方式类似。</p><pre><code>//方式 1![如果图片不能显示，就显示这段文字](图片 url)//方式 2![如果图片不能显示，就显示这段文字][Image-url][Image-url]: 图片url &quot;这是提示文字&quot;</code></pre><h4 id="反斜杠"><a href="#反斜杠" class="headerlink" title="反斜杠 \"></a>反斜杠 <code>\</code></h4><p>我们经常需要在文章中插入一些特殊符号，而这些符号恰好是前面所讲的标识符号，可以在特殊符号前插入 <code>\</code> 来直接显示符号，而不让 Markdown 来将其解释为标识符号。</p><p>Markdown 支持以下这些符号前插入 <code>\</code> 而显示其本来样子：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">\   反斜线</span><br><span class="line">`   反引号</span><br><span class="line">*   星号</span><br><span class="line">_   底线</span><br><span class="line">&#123;&#125;  花括号</span><br><span class="line">[]  方括号</span><br><span class="line">()  括弧</span><br><span class="line">#   井字号</span><br><span class="line">+   加号</span><br><span class="line">-   减号</span><br><span class="line">.   英文句点</span><br><span class="line">!   惊叹号</span><br></pre></td></tr></table></figure><h3 id="拓展"><a href="#拓展" class="headerlink" title="拓展"></a>拓展</h3><p>其实，市场上有很多的 Markdown 解释器，它们大都能支持上面所讲的语法，但呈现出的样式往往不一。另外，不同的解释器还能支持其他自己定义的语法，比如 Github 还能支持 emoji。下面再着重介绍 Github 支持的几个 Markdown 语法。不过需要注意的是，有些语法只能在 issue 或者 pull request 上使用，这个在后面讲每个语法时会标记（约定：“通用”表示在 Github 任何地方可以使用的语法，“特殊”表示只能在 issue 或者 pull request 上使用）。</p><h4 id="语法高亮-通用"><a href="#语法高亮-通用" class="headerlink" title="语法高亮(通用)"></a>语法高亮(通用)</h4><p>上面说过，有的解释器是能够显示语法高亮的，Github 就可以。</p><h4 id="任务列表（通用）"><a href="#任务列表（通用）" class="headerlink" title="任务列表（通用）"></a>任务列表（通用）</h4><pre><code>- [ ] task one- [x] task two</code></pre><p>用法跟普通列表的用法差不多，只不过在每一项文字前面加了 <code>[ ]</code> 或者 <code>[x]</code>。<code>[ ]</code> 中间有且只有一个空格，表示未完成，另一个表示已完成。</p><h4 id="表格（通用）"><a href="#表格（通用）" class="headerlink" title="表格（通用）"></a>表格（通用）</h4><p>Github 支持更简单的 table 语法。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">First Header | Second Header</span><br><span class="line">------------ | -------------</span><br><span class="line">Content from cell 1 | Content from cell 2</span><br><span class="line">Content in the first column | Content in the second column</span><br></pre></td></tr></table></figure><p>表头与项用一排 <code>-</code> 分隔开，每一列用 <code>|</code> 分隔开。</p><h4 id="SHA-引用（特殊）"><a href="#SHA-引用（特殊）" class="headerlink" title="SHA 引用（特殊）"></a>SHA 引用（特殊）</h4><p>每一次 commit 都会产生一个 id，用 <code>@id</code> 的方式可以链接到某个项目的特定的 commit。比如用 <code>jquery/jquery@1b9575b9d14399e9426b9eacdd92b3717846c3f2</code> 就能链接到 jquery 的一次 commit 记录上。</p><h4 id="issue-引用（特殊）"><a href="#issue-引用（特殊）" class="headerlink" title="issue 引用（特殊）"></a>issue 引用（特殊）</h4><p>用 <code>#1</code> 来引用当前 repo 的第一个 issue，也可以用 <code>jquery/jquery#1</code> 引用 jquery 的第一次 issue。</p><h4 id="（特殊）"><a href="#（特殊）" class="headerlink" title="@（特殊）"></a>@（特殊）</h4><p>用 <code>@</code> 来提醒目标用户。比如 <code>@CompileYouth</code> 可以 @ 到我。</p><h4 id="删除符号（通用）"><a href="#删除符号（通用）" class="headerlink" title="删除符号（通用）"></a>删除符号（通用）</h4><p>用连续两个 <code>~</code> 包围的词会被加上删除符。比如 <code>~~This is removed~~</code>。</p><h4 id="Emoji（通用）"><a href="#Emoji（通用）" class="headerlink" title="Emoji（通用）"></a>Emoji（通用）</h4><p>Github 比较有意思的是可以支持 emoji。比如 <code>:smile:</code> 表示笑脸等等，具体可以查看 <a href="http://www.webpagefx.com/tools/emoji-cheat-sheet/" target="_blank" rel="noopener">Emoji Cheat Sheet</a></p><p>详细信息可以查看<a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noopener">官方文档</a>。最后 po 两张 Github 官方推荐的 Markdown Cheat Sheet：<a href="./res/github-markdown-cheatsheet0.jpg">通用语法</a>，<a href="./res/github-markdown-cheatsheet1.jpg">Github 支持语法</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Markdown 是一种轻量级的标记语言，其用简单的标记语法便可达到排版的目的，其可以使我们更加专注于内容的编写，而不需过多关注排版。本文主要整理了 Markdown 中的常用的标记语法，以便自己与他人以后查用。&lt;/p&gt;
&lt;p&gt;Hexo是基于Github的博客平台，Github中的文本格式是.md，那么用Hexo写博客也必然要用到Markdown。本文首先带你选择适合你的Markdown编辑器(推荐Atom)，然后对Markdown语法做一简要介绍。&lt;/p&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="Github" scheme="https://baoyuzhang.github.io/tags/Github/"/>
    
      <category term="Hexo" scheme="https://baoyuzhang.github.io/tags/Hexo/"/>
    
      <category term="Markdown" scheme="https://baoyuzhang.github.io/tags/Markdown/"/>
    
  </entry>
  
  <entry>
    <title>【Hexo搭建独立博客全纪录】（一）使用Git和Github</title>
    <link href="https://baoyuzhang.github.io/2017/04/28/%E3%80%90Hexo%E6%90%AD%E5%BB%BA%E7%8B%AC%E7%AB%8B%E5%8D%9A%E5%AE%A2%E5%85%A8%E7%BA%AA%E5%BD%95%E3%80%91%EF%BC%88%E4%B8%80%EF%BC%89%E4%BD%BF%E7%94%A8Git%E5%92%8CGithub/"/>
    <id>https://baoyuzhang.github.io/2017/04/28/【Hexo搭建独立博客全纪录】（一）使用Git和Github/</id>
    <published>2017-04-28T02:57:39.000Z</published>
    <updated>2017-04-29T10:09:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>从开始着手搭建博客，完整的学习Git，Markdown语法，到用Hexo搭建博客成功，再到后期在原有主题的基础增加功能性和视觉上的优化，折腾了三四天，总算看倒腾出了一个看上去基本满意的博客。由于时间关系，还有很多想法没有实现，后面会不断地改进和优化。今天先来说一说学习使用Git和Github。</p><a id="more"></a><p>去年十月第一次接触Github，慕名而来，当时觉得这是一个高的触不可及的平台，我等渣渣还是退下吧…直到今年过完年回来二月份才开始真正使用Github，不熟悉命令行的我对Git Bush是绕着走的，在慕课网上看到Github可以使用友好的图形化客户端来操作，心中一阵窃喜。现在看来，当时真是too young too simple，因为命令行真的是好用啊！而且一点都不难，so easy~当初用客户端还把自己搞得晕晕乎乎的，当时在想这东西这么复杂怎么还这么火，还怀疑自己是不是不适合做程序员…本以为自己走了捷径，却害苦了自己！好了，闲话到此为止，进入正题。</p><p>结论：拒绝客户端，直接学习Git！</p><p>学习Git和Github，我主要是跟着<a href="http://www.cnblogs.com/tugenhua0707/p/4050072.html" target="_blank" rel="noopener">Git使用教程</a>来做的，文中每一步都有图和解释，超详细，手把手教你使用Git和Github，极力推荐给正在入门的小白！参考该教程、文后的链接和我自己的理解，构成本文的内容。由于目前个人用不到多人协作，因此本文并未提及，如有需要，也请参考<a href="http://www.cnblogs.com/tugenhua0707/p/4050072.html" target="_blank" rel="noopener">Git使用教程</a>。</p><p>此处列出了一些我收藏的公认的比较好的Git教程，可以作为深入学习资料</p><ul><li><p><a href="http://www.cnblogs.com/tugenhua0707/p/4050072.html" target="_blank" rel="noopener">Git使用教程</a> 本文主要参考</p></li><li><p><a href="http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000" target="_blank" rel="noopener">Git教程 - 廖雪峰的官方网站</a> 大牛博客，还包含JS，Python等教程，都很棒</p></li><li><p><a href="http://www.bootcss.com/p/git-guide/" target="_blank" rel="noopener">git 使用简易指南</a></p></li><li><p><a href="http://marklodato.github.io/visual-git-guide/index-zh-cn.html" target="_blank" rel="noopener">图解Git</a> 图文并茂，对git工作原理的理解帮助很大</p></li><li><p><a href="https://git-scm.com/book/zh/v2" target="_blank" rel="noopener">Git - Book</a></p></li><li><p><a href="https://guides.github.com/" target="_blank" rel="noopener">GitHub Guides</a> GitHub官方指南，很多都有中文翻译，可以自己搜一下</p></li><li><p><a href="http://gitbeijing.com/flow/" target="_blank" rel="noopener">理解 GitHub Flow · GitHub 指南</a> 理解Github工作原理，GitHub官方指南中文翻译的一部分</p></li></ul><h2 id="Git简介"><a href="#Git简介" class="headerlink" title="Git简介"></a>Git简介</h2><h3 id="Git是什么？"><a href="#Git是什么？" class="headerlink" title="Git是什么？"></a>Git是什么？</h3><p>Git是目前世界上最先进的分布式版本控制系统。</p><h3 id="SVN（集中式）与Git（分布式）的最主要的区别？"><a href="#SVN（集中式）与Git（分布式）的最主要的区别？" class="headerlink" title="SVN（集中式）与Git（分布式）的最主要的区别？"></a>SVN（集中式）与Git（分布式）的最主要的区别？</h3><p>SVN是集中式版本控制系统，版本库集中放在中央服务器。干活的时候用自己的电脑，首先要从中央服务器哪里得到最新的版本，然后干活，干完后把自己做完的活推送到中央服务器。集中式版本控制系统必须联网才能工作，如果在局域网还可以，带宽够大，速度够快，如果在互联网下，如果网速慢的话，就难办了。</p><p>Git是分布式版本控制系统，没有中央服务器。每个人的电脑就是一个完整的版本库，工作的时候不需要联网。既然每个人的电脑都有一个完整的版本库，那多个人如何协作呢？比如说自己在电脑上改了文件A，其他人也在电脑上改了文件A，这时，你们俩只需把各自的修改推送给对方，就可以互相看到对方的修改了。</p><h2 id="安装Git（windows）"><a href="#安装Git（windows）" class="headerlink" title="安装Git（windows）"></a>安装Git（windows）</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>建议到<a href="https://git-scm.com/" target="_blank" rel="noopener">Git官网</a>下载最新版本，国内访问会很慢，可以到网上搜索下载，然后默认安装即可。安装完成后，在开始菜单里面找到 “Git –&gt; Git Bash”，如下：<br><img src="/img/01.jpg" alt="&quot;Git --&gt; Git Bash&quot;"></p><p>弹出一个类似的命令窗口的东西，就说明Git安装成功。如下：<br><img src="/img/2017-04-28_165817.png" alt="&quot;git安装成功&quot;"></p><h3 id="设置用户名和邮箱"><a href="#设置用户名和邮箱" class="headerlink" title="设置用户名和邮箱"></a>设置用户名和邮箱</h3><p>因为Git是分布式版本控制系统，所以需要填写用户名和邮箱作为一个标识。在命令行输入如下：<br><img src="/img/2017-04-28_171200.png" alt="&quot;设置邮箱和用户名&quot;"></p><p><strong>注意！</strong><code>git config  --global</code> 参数，表示你这台机器上所有的Git仓库都会使用这个配置，当然你也可以对某个仓库指定的不同的用户名和邮箱。</p><p>查看已设置的用户名和邮箱，在命令行输入如下：<br><img src="/img/2017-04-28_171259.png" alt="&quot;查看邮箱和用户名&quot;"></p><h2 id="使用Git"><a href="#使用Git" class="headerlink" title="使用Git"></a>使用Git</h2><h3 id="创建版本库repository"><a href="#创建版本库repository" class="headerlink" title="创建版本库repository"></a>创建版本库repository</h3><p>版本库：又名仓库，英文名repository。可简单的理解一个目录，这个目录里面的所有文件都会被Git管理，每个文件的修改，删除，Git都能跟踪，以便任何时刻都可以追踪历史，或者在将来某个时刻还可以将文件“还原”。</p><table><thead><tr><th>命令</th><th>释义</th></tr></thead><tbody><tr><td><strong>打开所在目录</strong></td><td></td></tr><tr><td>cd folder</td><td>打开文件夹</td></tr><tr><td>mkdir folder</td><td>新建文件夹</td></tr><tr><td>pwd</td><td>显示当前目录</td></tr><tr><td><strong>初始化：将当前目录变为git仓库</strong></td><td></td></tr><tr><td>git init</td><td>当前目录→git可管理仓库</td></tr><tr><td><strong>添加文件到版本库</strong></td><td></td></tr><tr><td>git add file</td><td>将file文件添加到暂存区</td></tr><tr><td>git commit -m “提交说明”</td><td>将暂存区中所有文件提交到仓库</td></tr><tr><td>git status</td><td>查看当前目录中是否有文件未提交</td></tr></tbody></table><h4 id="打开所在目录"><a href="#打开所在目录" class="headerlink" title="打开所在目录"></a>打开所在目录</h4><p>创建一个版本库，如在D:/www下 目录下新建一个testgit版本库，在命令行输入如下：<br><img src="/img/2017-04-28_173436.png" alt="&quot;创建版本库&quot;"></p><h4 id="初始化：将当前目录变为git仓库"><a href="#初始化：将当前目录变为git仓库" class="headerlink" title="初始化：将当前目录变为git仓库"></a>初始化：将当前目录变为git仓库</h4><p><img src="/img/2017-04-28_174138.png" alt="&quot;初始化&quot;"></p><p><strong>注意！</strong> 这时当前testgit目录下会多一个.git的目录，这个目录是Git来跟踪管理版本的，千万不要手动乱改这个目录里面的文件，否则，会把git仓库给破坏了。如下：<br><img src="/img/2017-04-28_174458.png" alt="&quot;.git&quot;"></p><h4 id="添加文件到版本库"><a href="#添加文件到版本库" class="headerlink" title="添加文件到版本库"></a>添加文件到版本库</h4><p>作为测试，在当前目录下新建一个readme.txt，并写入11111111保存，之后进行如下3步操作：<br><img src="/img/2017-04-28_180144.png" alt="&quot;添加文件到版本库&quot;"></p><p><code>git status</code> 结果显示没有任何文件未提交。</p><h3 id="修改和版本回退"><a href="#修改和版本回退" class="headerlink" title="修改和版本回退"></a>修改和版本回退</h3><table><thead><tr><th>命令</th><th>释义</th></tr></thead><tbody><tr><td><strong>修改文件内容</strong></td><td></td></tr><tr><td>git diff file</td><td>查看file文件修改内容</td></tr><tr><td><strong>查看历史记录</strong></td><td></td></tr><tr><td>git log</td><td>查看历史记录</td></tr><tr><td>git log –pretty=oneline</td><td>查看历史记录（简洁版）</td></tr><tr><td><strong>版本回退</strong></td><td></td></tr><tr><td>git reset –hard HEAD^</td><td>退回到上个版本</td></tr><tr><td>git reset –hard HEAD^^</td><td>退回到上上个版本</td></tr><tr><td>git reset –hard HEAD~100</td><td>退回到前100个版本</td></tr><tr><td><strong>恢复最新版本</strong></td><td></td></tr><tr><td>git reflog</td><td>获取全部版本号</td></tr><tr><td>git reset –hard 版本号</td><td>退回到版本号的版本</td></tr><tr><td>cat file</td><td>查看文件内容</td></tr></tbody></table><h4 id="修改文件内容"><a href="#修改文件内容" class="headerlink" title="修改文件内容"></a>修改文件内容</h4><p>继续，修改readme.txt内容，在下面添加一行22222222内容，继续使用git status查看结果，如下：<br><img src="/img/2017-04-28_211211.png" alt="&quot;git status&quot;"></p><p> 结果显示，readme.txt文件已被修改，但是未被提交的修改。接下来我想看下readme.txt文件到底改了什么内容，如何查看呢？可以使用如下命令：<br> <img src="/img/2017-04-28_211553.png" alt="&quot;git diff&quot;"></p><p> 结果显示，readme.txt文件内容从一行11111111改成两行，添加了一行22222222内容。</p><p> 知道了对readme.txt文件做了什么修改后，我们可以放心的提交到仓库了，提交修改和提交文件是一样的两步(第一步是git add  第二步是：git commit)。如下：<br> <img src="/img/2017-04-28_212240.png" alt="&quot;增加222&quot;"></p><p><code>git status</code>：提交文件之前，查看一下状态；提交文件之后，继续查看一下状态，显示没有可提交的文件</p><p><strong>说明：</strong> 所有的版本控制系统，只能跟踪文本文件的改动（如txt文件，网页，所有程序的代码等）。对于图片，视频这些二进制文件，只能把每次改动串起来，无法跟踪文件的变化，即：知道图片从1kb变成2kb，但是到底改了什么，版本控制系统也不知道</p><h4 id="查看历史记录"><a href="#查看历史记录" class="headerlink" title="查看历史记录"></a>查看历史记录</h4><p>继续对readme.txt文件进行修改，再增加一行<br>内容为33333333，然后执行命令如下：<br><img src="/img/2017-04-28_213243.png" alt="&quot;增加333内容&quot;"></p><p>现在我已经对readme.txt文件做了三次修改了，那么我现在想查看下历史记录，如何查看呢？使用命令 <code>git log</code> ,如下：<br><img src="/img/2017-04-28_213915.png" alt="&quot;git log&quot;"></p><p>结果显示，从最近到最远的显示日志，我们可以看到最近三次提交，最近的一次是“增加333内容”，上一次是“增加222内容”。</p><p>如果嫌上面显示的信息太多的话，可以用缩减版显示，如下：<br><img src="/img/2017-04-28_214341.png" alt="&quot;git log --pretty=oneline&quot;"></p><h4 id="版本回退"><a href="#版本回退" class="headerlink" title="版本回退"></a>版本回退</h4><p>现在我想使用版本回退操作，我想把当前的版本回退到上一个版本，要使用什么命令呢？可以使用如下2种命令，第一种是<code>git reset  --hard HEAD^</code> ；那么如果要回退到上上个版本只需把<code>HEAD^ 改成 HEAD^^</code>， 以此类推。那如果要回退到前100个版本的话，使用上面的方法肯定不方便，我们可以使用下面的简便命令操作：<code>git reset  --hard HEAD~100</code> 即可。未回退之前的readme.txt内容如下：<br><img src="/img/2017-04-28_214610.png" alt="&quot;未回退内容&quot;"></p><p>回退到上一个版本，如下<br><img src="/img/2017-04-28_214824.png" alt="&quot;回退到上一个版本&quot;"></p><p>查看现在readme.txt文件中的内容，如下：<br><img src="/img/2017-04-28_214936.png" alt="&quot;查看内容&quot;"></p><p>结果显示，”增加333内容”我们没有看到了。</p><h4 id="恢复最新版本"><a href="#恢复最新版本" class="headerlink" title="恢复最新版本"></a>恢复最新版本</h4><p>现在我想恢复到最新的版本(有333333内容版本)要如何恢复呢？可以通过版本号回退。</p><p>但是现在的问题假如我已经关掉过一次git bush，或者333内容的版本号我并不知道呢？要如何知道增加3333内容的版本号呢？如下：<br><img src="/img/2017-04-28_215744.png" alt="&quot;查看版本号&quot;"></p><p>结果显示，”增加333内容”的版本号是 c83a6bb。现在可以通过版本号回退了，如下：<br><img src="/img/2017-04-28_220020.png" alt="&quot;版本号回退&quot;"></p><p>结果显示，目前已经是最新的版本。</p><h4 id="理解工作区、暂存区、版本库"><a href="#理解工作区、暂存区、版本库" class="headerlink" title="理解工作区、暂存区、版本库"></a>理解工作区、暂存区、版本库</h4><p><strong>工作区：</strong> 你在电脑上看到的目录，比如目录testgit里的文件(.git隐藏目录版本库除外)，以后需要再新建的目录文件等等都属于工作区范畴。</p><p><strong>版本库：</strong> 工作区里的隐藏目录.git，这个不属于工作区，这是版本库。版本库中存了很多东西：</p><ul><li><strong>暂存区(stage)</strong> ——最重要！（暂存区是版本库的一部分）</li><li>Git为我们自动创建了第一个分支master</li><li>指向当前分支的指针HEAD</li></ul><p>前面说过使用Git提交文件到版本库有两步：</p><ul><li><p>第一步：<code>git add</code> 把文件添加进去，实际上就是把文件添加到暂存区；</p></li><li><p>第二步：<code>git commit</code> 提交更改，实际上就是把暂存区的所有内容提交到当前分支上。</p></li></ul><p>下面来举例说明。</p><p>在readme.txt再添加一行内容为4444444，接着在目录下新建一个文件为test.txt 内容为test，我们先用命令<code>git status</code>来查看下状态，如下：<br><img src="/img/2017-04-28_222758.png" alt="&quot;工作区、暂存区、版本库&quot;"></p><p>先使用git add 命令把2个文件都添加到暂存区中，再使用git status来查看下状态，如下：<br><img src="/img/2017-04-28_223111.png" alt="&quot;git add&quot;"></p><p>接着使用git commit一次性提交到分支上，如下：<br><img src="/img/2017-04-28_223236.png" alt="&quot;一次性提交所有文件&quot;"></p><h3 id="撤销修改、删除和恢复文件"><a href="#撤销修改、删除和恢复文件" class="headerlink" title="撤销修改、删除和恢复文件"></a>撤销修改、删除和恢复文件</h3><table><thead><tr><th>命令</th><th>释义</th><th>备注</th></tr></thead><tbody><tr><td><strong>撤销修改</strong></td><td></td><td></td></tr><tr><td>git checkout – file</td><td>丢弃file文件在工作区的修改（工作区-暂存区-版本库，回到上一阶段的修改）a.工作区修改后没有add到暂存区：回到和版本库一样的状态；b.工作区修改后add到暂存区后又有修改：回到添加暂存区后的状态</td><td>如果没有–，则为创建分支命令</td></tr><tr><td><strong>删除和恢复文件</strong></td><td></td><td></td></tr><tr><td>rm file</td><td>删除工作区中的file文件</td><td>a.想要删除版本库中的file文件：直接commit掉；b.想要从版本库中删除file文件：git checkout – file</td></tr><tr><td>git checkout – file</td><td>丢弃file文件在工作区的修改（工作区-暂存区-版本库，回到上一阶段的修改）a.工作区修改后没有add到暂存区：回到和版本库一样的状态；b.工作区修改后add到暂存区后又有修改：回到添加暂存区后的状态</td><td>如果没有–，则为创建分支命令</td></tr></tbody></table><h4 id="撤销修改"><a href="#撤销修改" class="headerlink" title="撤销修改"></a>撤销修改</h4><p>现在在readme.txt文件里面增加一行内容为55555555，通过命令查看如下：<br><img src="/img/2017-04-28_223816.png" alt="&quot;修改555&quot;"></p><p>在未提交之前，我发现添加55555555内容有误，得马上恢复以前的版本，现在我可以有如下几种方法可以做修改：</p><ol><li><p>如果知道要删掉哪些内容，直接手动更改去掉那些需要的文件，然后add添加到暂存区，最后commit。</p></li><li><p>按以前的方法直接恢复到上一个版本。使用 <code>git reset  --hard HEAD^</code></p></li></ol><p>但是现在我不想使用以上两种方法，想直接使用撤销命令该如何操作呢？首先在做撤销之前，我们可以先用 git status 查看下当前的状态，如下：<br><img src="/img/2017-04-28_224044.png" alt="&quot;git status&quot;"></p><p>可以发现，Git会告诉你，<code>git checkout  -- file</code> 可以将工作区做的修改全部撤销，如下:<br><img src="/img/2017-04-28_224304.png" alt="&quot;git checkout&quot;"></p><p><strong>注意：</strong> <code>git checkout -- readme.txt</code> 中的 <code>--</code> 很重要.如果没有 <code>--</code> ，则命令变成创建分支了。</p><p>结果显示，内容555已结没有了。将工作区做的修改全部撤销有两种情况：</p><ol><li>修改后还没有放到暂存区：撤销修改则回到和版本库一模一样的状态；</li><li>已经放入暂存区，接着又作了修改：撤销修改则回到添加暂存区后的状态。</li></ol><p>对于第2种情况，继续做demo，假如现在对readme.txt添加一行内容为66666666，git add 增加到暂存区，如下：<br><img src="/img/2017-04-28_225212.png" alt="&quot;add 666&quot;"></p><p>接着添加内容77777777，通过撤销命令让其回到暂存区后的状态。如下：<br><img src="/img/2017-04-28_225241.png" alt="&quot;撤销777&quot;"></p><h4 id="删除和恢复文件"><a href="#删除和恢复文件" class="headerlink" title="删除和恢复文件"></a>删除和恢复文件</h4><p> 假如现在版本库testgit目录添加一个文件a.txt，然后提交。如下：<br> <img src="/img/2017-04-28_230315.png" alt="&quot;添加a.txt&quot;"></p><p>一般情况下，删除文件有两种方法：</p><ol><li>直接在文件目录中删除文件text.txt</li><li>使用命令<code>rm a.txt</code></li></ol><p>如下：<br><img src="/img/2017-04-28_230736.png" alt="&quot;删除a.txt、test.txt&quot;"></p><p>当前目录是这样的:<br><img src="/img/2017-04-28_230825.png" alt="&quot;当前目录&quot;"></p><p>如果想彻底从版本库中删掉了此文件的话，可以再执行commit命令提交掉。没有commit之前，想在版本库中恢复此文件如何操作呢？如下：<br><img src="/img/2017-04-28_231517.png" alt="&quot;提交a.txt、test.txt&quot;"></p><p>再来看testgit目录，添加了2个文件，如下：<br><img src="/img/2017-04-28_231617.png" alt="&quot;当前目录&quot;"></p><h3 id="创建、合并分支"><a href="#创建、合并分支" class="headerlink" title="创建、合并分支"></a>创建、合并分支</h3><h4 id="理解HEAD和master指针"><a href="#理解HEAD和master指针" class="headerlink" title="理解HEAD和master指针"></a>理解HEAD和master指针</h4><p>你已经知道，在版本回退里，每次提交，Git都把它们串成一条时间线，这条时间线就是一个分支。截止到目前，只有一条时间线，在Git里，这个分支叫主分支，即master分支。严格来说，HEAD并不是指向提交，而是指向master，master才是指向提交的，所以，HEAD指向的就是当前分支。</p><p><strong>结论：HEAD指向当前分支，master指向提交</strong></p><h4 id="理解分支管理策略"><a href="#理解分支管理策略" class="headerlink" title="理解分支管理策略"></a>理解分支管理策略</h4><p><strong>master主分支：用来发布新版本，应该是非常稳定的。一般情况下不允许在上面干活。</strong><br><strong>一般情况下在新建的dev分支上干活，干完后，要发布，或者说dev分支代码稳定后可以合并到主分支master上来。</strong></p><table><thead><tr><th>命令</th><th>释义</th><th>备注</th></tr></thead><tbody><tr><td><strong>创建、合并分支</strong></td><td></td><td></td></tr><tr><td>git branch</td><td>查看分支</td><td>列出所有分支，当前分支前有星号</td></tr><tr><td>git branch xxx</td><td>创建分支xxx</td><td></td></tr><tr><td>git checkout xxx</td><td>切换到分支xxx</td><td></td></tr><tr><td>git checkout -b xxx</td><td>创建 + 切换分支xxx</td><td>相当于<code>git branch xxx</code>和<code>git checkout xxx</code></td></tr><tr><td>git merge xxx</td><td>在主分支上合并xxx分支</td><td>“Fast-forward“快进模式”：直接把master指向xxx的当前提交；删除分支后，丢掉分支信息CONFLICT：产生冲突；删除分支后，保留分支信息”</td></tr><tr><td>git branch -d xxx</td><td>删除分支xxx</td><td></td></tr><tr><td><strong>解决冲突</strong></td><td></td><td></td></tr><tr><td>git log –graph –pretty=oneline –abbrev-commit</td><td>带参数的git log，查看分支合并图</td><td>删除分支后，保留分支信息</td></tr><tr><td><strong>“Fast forward”模式 no-ff</strong></td><td></td><td></td></tr><tr><td>git merge –no-ff -m “merge with no-ff” xxx</td><td>合并分支xxx，–no-ff：禁用Fast-forward“快进模式”</td><td>删除分支后，保留分支信息</td></tr></tbody></table><h4 id="创建、合并分支-1"><a href="#创建、合并分支-1" class="headerlink" title="创建、合并分支"></a>创建、合并分支</h4><p>首先，我们来创建并切换到dev分支上，然后查看当前分支，如下：<br><img src="/img/2017-04-29_110228.png" alt="&quot;创建并切换到dev分支&quot;"></p><p><code>git checkout -b xxx</code>表示创建 + 切换分支，相当于<code>git branch xxx</code>和<code>git checkout xxx</code>。</p><p><code>git branch</code>表示查看分支，列出所有分支，当前分支前有星号。</p><p>首先我们来查看下readme.txt内容，接着添加内容77777777，再次查看内容并提交，如下：<br><img src="/img/2017-04-29_111013.png" alt="&quot;dev分支增加777&quot;"></p><p>dev分支工作已完成，现在切换到主分支master上，继续查看readme.txt内容，如下：<br><img src="/img/2017-04-29_111235.png" alt="&quot;切换到主分支&quot;"></p><p>我们发现内容777不见了，因为已经由dev分支切换到主分支了，主分支并没有增加777内容。现在我们把dev分支上的内容合并到分支master上，在master分支上，使用<code>git merge dev</code>，继续查看内容。如下：<br><img src="/img/2017-04-29_111547.png" alt="&quot;合并分支&quot;"></p><p>我们发现多了一条777，和dev分支最新的提交完全一样。</p><p><strong>注意！</strong> merge后显示的Fast-forward信息，表示这次合并是“快进模式”，即，直接把master指向dev的当前提交，合并速度非常快。</p><p>合并完成后，可以删除dev分支，如下：<br><img src="/img/2017-04-29_112129.png" alt="&quot;删除分支&quot;"></p><p>查看分支，发现只剩下主分支master了。</p><h4 id="解决冲突"><a href="#解决冲突" class="headerlink" title="解决冲突"></a>解决冲突</h4><p>那么如何解决冲突呢？我们还是一步一步来，先新建一个新分支fenzhi1，在readme.txt添加一行内容8888888，然后提交，如下：<br><img src="/img/2017-04-29_112708.png" alt="&quot;fenzhi1分支添加888&quot;"></p><p>接着切换到master分支上，在最后一行添加内容99999999，如下：<br><img src="/img/2017-04-29_112957.png" alt="&quot;主分支添加999&quot;"></p><p>现在，在master分支上合并fenzhi1，如下：<br><img src="/img/2017-04-29_113150.png" alt="&quot;主分支上合并fenzhi1&quot;"></p><p>发现发生了冲突CONFLICT，git bush中显示分支的地方也变成了(master|MERGING)。查看状态和readme.txt内容，如下：<br><img src="/img/2017-04-29_113734.png" alt="&quot;查看状态和内容&quot;"><br><img src="/img/2017-04-29_114045.png" alt="&quot;查看状态和内容&quot;"></p><p>Git用&lt;&lt;&lt;&lt;&lt;&lt;&lt;，=======，&gt;&gt;&gt;&gt;&gt;&gt;&gt;标记出不同分支的内容。</p><ul><li><code>&lt;&lt;&lt;HEAD</code> ：主分支修改的内容</li><li><code>&gt;&gt;&gt;&gt;&gt;fenzhi1</code> ：fenzhi1上修改的内容</li></ul><p>修改readme.txt内容后，保存并提交，如下：<br><img src="/img/2017-04-29_114214.png" alt="&quot;修改readme.txt内容&quot;"><br><img src="/img/2017-04-29_115156.png" alt="&quot;修改readme.txt内容&quot;"></p><p>发现显示分支的地方变回了(master)。如果想要查看分支合并的情况，需要使用命令 <code>git log</code>命令，如下：<br><img src="/img/2017-04-29_115518.png" alt="&quot;git log&quot;"></p><p><code>git log</code>展示的信息量太大，一片文字看不过来，使用<code>git log --graph --pretty=oneline --abbrev-commit</code>命令可以显示分支合并图，如下：<br><img src="/img/2017-04-29_120112.png" alt="&quot;分支合并图&quot;"></p><h4 id="“Fast-forward”模式-no-ff"><a href="#“Fast-forward”模式-no-ff" class="headerlink" title="“Fast forward”模式 no-ff"></a>“Fast forward”模式 no-ff</h4><p>通常合并分支时，git一般使用”Fast forward”模式，在这种模式下，删除分支后，会丢掉分支信息。</p><p>现在我们来使用带参数 –no-ff来禁用”Fast forward”模式。来做demo演示下：</p><ol><li>创建一个dev分支</li><li>修改readme.txt内容，增加aaa</li><li>添加到暂存区</li><li>切换回主分支(master)</li><li>合并dev分支，使用命令 <code>git merge -–no-ff  -m “注释” dev</code></li><li>删除dev分支</li><li>查看分支</li><li>查看历史记录</li></ol><p>如下：<br><img src="/img/2017-04-29_142402.png" alt="&quot;no-ff&quot;"></p><h3 id="bug分支"><a href="#bug分支" class="headerlink" title="bug分支"></a>bug分支</h3><table><thead><tr><th>命令</th><th>b释义</th></tr></thead><tbody><tr><td>git stash</td><td>隐藏当前分支的工作现场</td></tr><tr><td>git stash list</td><td>查看stash隐藏的内容</td></tr><tr><td>git stash apply</td><td>恢复stash隐藏内容</td></tr><tr><td>git stash drop</td><td>删除stash内容</td></tr><tr><td>git stash pop</td><td>恢复并删除stash隐藏内容</td></tr></tbody></table><p>在开发中，会经常碰到bug问题，那么有了bug就需要修复，在Git中，分支是很强大的，每个bug都可以通过一个临时分支来修复，修复完成后，合并分支，然后将临时的分支删除掉。</p><p>来做demo演示：新建dev分支，在readme.txt中增加bbb。此时接到一个404 bug，我们可以创建一个404分支来修复它，但是，当前的dev分支上的工作还没有提交。如下：<br><img src="/img/2017-04-29_144313.png" alt="&quot;遇到404 bug&quot;"></p><p>并不是我不想提交，而是工作进行到一半时候，我们还无法提交，比如我这个分支bug要2天完成，但是我issue-404 bug需要5个小时内完成。怎么办呢？还好，Git还提供了一个stash功能，可以把当前工作现场 ”隐藏起来”，等以后恢复现场后继续工作。如下：<br><img src="/img/2017-04-29_144452.png" alt="&quot;stash隐藏工作现场&quot;"></p><p>查看状态显示，<code>nothing to commit, working directory clean</code>，说明工作现场已被隐藏。现在可以通过创建issue-404分支来修复bug了。</p><p>首先要确定在哪个分支上修复bug。假设我现在要在主分支master上修复，那么要切换到主分支master，然后创建一个临时分支issue-404，如下：<br><img src="/img/2017-04-29_145356.png" alt="&quot;临时分支issue-404&quot;"></p><p>修复404bug：将最后一行aaa改为404fixed，然后提交，如下：<br><img src="/img/2017-04-29_145603.png" alt="&quot;修复404bug&quot;"></p><p>修复完成，切换到master分支上，并完成合并，最后删除issue-404分支。如下：<br><img src="/img/2017-04-29_145845.png" alt="&quot;完成合并，删除issue-404分支&quot;"></p><p>现在，可以回到dev分支上干活了。<br><img src="/img/2017-04-29_150024.png" alt="&quot;回到dev分支&quot;"></p><p>查看状态表明，现在的工作区是干净的。那么我们工作现场去哪里呢？我们可以使用命令 git stash list来查看下。如下：<br><img src="/img/2017-04-29_150228.png" alt="&quot;git stash list&quot;"></p><p>工作现场还在，Git把stash内容存在某个地方了，但是需要恢复一下，可以使用如下2个方法：</p><ol><li>git stash apply恢复。恢复后，stash内容并不删除，你需要使用命令git stash drop来删除</li><li>使用git stash pop。恢复的同时把stash内容也删除了</li></ol><p>如下：<br><img src="/img/2017-04-29_151622.png" alt="&quot;恢复工作区&quot;"></p><p>这样就恢复了之前的工作区，可以继续dev分支的工作了。</p><h2 id="Github远程仓库"><a href="#Github远程仓库" class="headerlink" title="Github远程仓库"></a>Github远程仓库</h2><table><thead><tr><th>命令</th><th>b释义</th><th>备注</th></tr></thead><tbody><tr><td><strong>创建SSH Key</strong></td><td></td><td></td></tr><tr><td>ssh-keygen -t rsa –C “<a href="mailto:youremail@example.com" target="_blank" rel="noopener">youremail@example.com</a>”</td><td>创建SSH Key</td><td>id_rsa是私钥，不能泄露出去;id_rsa.pub是公钥，可以放心地告诉任何人”</td></tr><tr><td><strong>Github中添加SSH Key</strong></td><td></td><td></td></tr><tr><td><strong>添加远程库</strong></td><td></td><td></td></tr><tr><td><strong>a.先创建本地git仓库，再创建github仓库，两个仓库同步</strong></td><td></td><td></td></tr><tr><td>git remote add origin <a href="https://github.com/xxx/xxx.git" target="_blank" rel="noopener">https://github.com/xxx/xxx.git</a></td><td>添加github地址</td><td></td></tr><tr><td>git push -u origin master</td><td>第一次使用时执行该命令，将本地的master分支和远程的master分支关联起来，并把将其推送到远程”</td><td></td></tr><tr><td>git push origin master</td><td>将本地master分支的最新修改推送到github</td><td></td></tr><tr><td><strong>b.先创建github仓库，再从github仓库</strong></td><td></td><td></td></tr><tr><td>git clone <a href="https://github.com/xxx/xxx" target="_blank" rel="noopener">https://github.com/xxx/xxx</a></td><td></td><td></td></tr></tbody></table><p>先注册github账号，由于你的本地Git仓库和github仓库之间的传输是通过SSH加密的，所以需要设置SSH Key。</p><h3 id="创建SSH-Key"><a href="#创建SSH-Key" class="headerlink" title="创建SSH Key"></a>创建SSH Key</h3><p>查看是否已经有ssh密钥：<br>打开用户主目录”C:\Users\Administrator.hp-PC”，<br>看看有没有.ssh目录。</p><ul><li>如果有，再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件。如果有，可以直接跳至下一小节</li><li>如果已经有ssh密钥，想要重新生成ssh密钥，需要清理原有ssh密钥：<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir key_backup</span><br><span class="line">$ cp id_rsa* key_backup</span><br><span class="line">$ rm id_rsa*</span><br></pre></td></tr></table></figure></li><li><p>如果没有，打开命令行，输入命令<code>ssh-keygen  -t rsa –C “youremail@example.com”</code>。此处的邮箱地址，你可以输入自己的邮箱地址。在回车中会提示你输入一个密码，这个密码会在你提交项目时使用，如果为空的话提交项目时则不用输入。这个设置是防止别人往你的项目里提交内容。</p><p>由于我本地此前运行过一次，所以本地有，如下所示：</p></li></ul><p><img src="/img/2017-04-29_153448.png" alt="&quot;.ssh&quot;"></p><p>id_rsa是私钥，不能泄露出去，id_rsa.pub是公钥，可以放心地告诉任何人。由于之前使用Github客户端，因此还有github_rsa和github_rsa.pub两个文件。known_hosts文件如果没有暂时不管。</p><p>验证是否连接成功，连接成功显示<code>Hi baoyuzhang! You&#39;ve successfully authenticated, but GitHub does not provide shell access.</code>。如下：<br><img src="/img/2017-04-29_160356.png" alt="&quot;验证是否连接成功&quot;"></p><h3 id="Github中添加SSH-Key"><a href="#Github中添加SSH-Key" class="headerlink" title="Github中添加SSH Key"></a>Github中添加SSH Key</h3><p>登录github，点击个人头像打开”settings”，再打开”SSH and GPG keys”页面，然后点击”New SSH Key”，填上任意title，在”Key”文本框里黏贴id_rsa.pub文件的内容，点击 Add Key，你就应该可以看到已经添加的key。如下：<br><img src="/img/2017-04-29_155435.png" alt="&quot;Github中添加SSH Key&quot;"></p><h3 id="添加远程库"><a href="#添加远程库" class="headerlink" title="添加远程库"></a>添加远程库</h3><h4 id="先创建本地git仓库，再创建github仓库，两个仓库同步"><a href="#先创建本地git仓库，再创建github仓库，两个仓库同步" class="headerlink" title="先创建本地git仓库，再创建github仓库，两个仓库同步"></a>先创建本地git仓库，再创建github仓库，两个仓库同步</h4><p>现在的情景是：我们已经在本地创建了一个Git仓库后，又想在github创建一个Git仓库，并且希望这两个仓库进行远程同步，这样github的仓库可以作为备份，又可以其他人通过该仓库来协作。</p><p>首先，登录github上，然后在右上角点击”+”找到”New repository”创建一个新的仓库。如下：<br><img src="/img/2017-04-29_161046.png" alt="&quot;create a new repo&quot;"><br><img src="/img/2017-04-29_161331.png" alt="&quot;create a new repo&quot;"></p><p>在Repository name填入testgit，其他保持默认设置，点击“Create repository”按钮，就成功地创建了一个新的Git仓库：<br><img src="/img/2017-04-29_161433.png" alt="&quot;new repo&quot;"></p><p>目前，在GitHub上的这个testgit仓库还是空的。现在把已有的本地仓库testgit与之关联，然后，把本地仓库的内容推送到GitHub仓库。<br><img src="/img/2017-04-29_162558.png" alt="&quot;推送到GitHub仓库&quot;"></p><p>把本地库的内容推送到远程，使用 git push命令，实际上是把当前分支master推送到远程。</p><p>由于远程库是空的，我们第一次推送master分支时，加上了 –u参数，Git不但会把本地的master分支内容推送的远程新的master分支，还会把本地的master分支和远程的master分支关联起来，在以后的推送或者拉取时就可以简化命令。推送成功后，可以立刻在github页面中看到远程库的内容已经和本地一模一样了：<br><img src="/img/2017-04-29_163139.png" alt="&quot;一模一样&quot;"></p><p>从现在起，只要本地作了提交，通过命令<code>git push origin master</code>就可以把本地master分支的最新修改推送到github上了，现在你就拥有了真正的分布式版本库了。</p><h4 id="先创建github仓库，再从github仓库克隆"><a href="#先创建github仓库，再从github仓库克隆" class="headerlink" title="先创建github仓库，再从github仓库克隆"></a>先创建github仓库，再从github仓库克隆</h4><p>上面我们了解了先有本地库，后有远程库时候，如何关联远程库。现在我们想，假如远程库有新的内容了，我想克隆到本地来 如何克隆呢？</p><p>首先，登录github，创建一个新的仓库，名字叫testgit2.如下：<br><img src="/img/2017-04-29_161046.png" alt="&quot;create a new repo&quot;"><br><img src="/img/2017-04-29_163601.png" alt="&quot;create a new repo&quot;"><br><img src="/img/2017-04-29_163651.png" alt="&quot;create a new repo&quot;"></p><p>现在，远程库已经准备好了，下一步是使用命令git clone克隆一个本地库了。如下：<br><img src="/img/2017-04-29_164025.png" alt="&quot;克隆一个本地库&quot;"><br>在本地目录就生成了testgit2目录，如下：<br><img src="/img/2017-04-29_164053.png" alt="&quot;克隆一个本地库&quot;"></p><h2 id="Git常用指令"><a href="#Git常用指令" class="headerlink" title="Git常用指令"></a>Git常用指令</h2><table><thead><tr><th>命令</th><th>b释义</th><th>备注</th></tr></thead><tbody><tr><td><strong>1.创建版本库repository</strong></td><td></td><td></td></tr><tr><td><strong>打开所在目录</strong></td><td></td><td></td></tr><tr><td>cd folder</td><td>打开文件夹</td><td></td></tr><tr><td>mkdir folder</td><td>新建文件夹</td><td></td></tr><tr><td>pwd</td><td>显示当前目录</td><td></td></tr><tr><td><strong>初始化：将当前目录变为git仓库</strong></td><td></td><td></td></tr><tr><td>git init</td><td>当前目录→git可管理仓库</td><td></td></tr><tr><td><strong>添加文件到版本库</strong></td><td></td><td></td></tr><tr><td>git add file</td><td>将file文件添加到暂存区</td><td></td></tr><tr><td>git commit -m “提交说明”</td><td>将暂存区中所有文件提交到仓库</td><td></td></tr><tr><td>git status</td><td>查看当前目录中是否有文件未提交</td><td></td></tr><tr><td><strong>2.修改和版本回退</strong></td><td></td><td></td></tr><tr><td><strong>修改文件内容</strong></td><td></td><td></td></tr><tr><td>git diff file</td><td>查看file文件修改内容</td><td></td></tr><tr><td><strong>查看历史记录</strong></td><td></td><td></td></tr><tr><td>git log</td><td>查看历史记录</td><td></td></tr><tr><td>git log –pretty=oneline</td><td>查看历史记录（简洁版）</td><td></td></tr><tr><td><strong>版本回退</strong></td><td></td><td></td></tr><tr><td>git reset –hard HEAD^</td><td>退回到上个版本</td><td></td></tr><tr><td>git reset –hard HEAD^^</td><td>退回到上上个版本</td><td></td></tr><tr><td>git reset –hard HEAD~100</td><td>退回到前100个版本</td><td></td></tr><tr><td><strong>恢复最新版本</strong></td><td></td><td></td></tr><tr><td>git reflog</td><td>获取全部版本号</td><td></td></tr><tr><td>git reset –hard 版本号</td><td>退回到版本号的版本</td><td></td></tr><tr><td>cat file</td><td>查看文件内容</td><td></td></tr><tr><td><strong>3.撤销修改、删除文件、恢复文件</strong></td><td></td><td></td></tr><tr><td><strong>撤销修改</strong></td><td></td><td></td></tr><tr><td>git checkout – file</td><td>丢弃file文件在工作区的修改（工作区-暂存区-版本库，回到上一阶段的修改）a.工作区修改后没有add到暂存区：回到和版本库一样的状态；b.工作区修改后add到暂存区后又有修改：回到添加暂存区后的状态</td><td>如果没有–，则为创建分支命令</td></tr><tr><td><strong>删除和恢复文件</strong></td><td></td><td></td></tr><tr><td>rm file</td><td>删除工作区中的file文件</td><td>a.想要删除版本库中的file文件：直接commit掉；b.想要从版本库中删除file文件：git checkout – file</td></tr><tr><td>git checkout – file</td><td>丢弃file文件在工作区的修改（工作区-暂存区-版本库，回到上一阶段的修改）a.工作区修改后没有add到暂存区：回到和版本库一样的状态；b.工作区修改后add到暂存区后又有修改：回到添加暂存区后的状态</td><td>如果没有–，则为创建分支命令</td></tr><tr><td><strong>4.创建、合并分支</strong></td><td></td><td></td></tr><tr><td><strong>创建、合并分支</strong></td><td></td><td></td></tr><tr><td>git branch</td><td>查看分支</td><td>列出所有分支，当前分支前有星号</td></tr><tr><td>git branch xxx</td><td>创建分支xxx</td><td></td></tr><tr><td>git checkout xxx</td><td>切换到分支xxx</td><td></td></tr><tr><td>git checkout -b xxx</td><td>创建 + 切换分支xxx</td><td>相当于<code>git branch xxx</code>和<code>git checkout xxx</code></td></tr><tr><td>git merge xxx</td><td>在主分支上合并xxx分支</td><td>“Fast-forward“快进模式”：直接把master指向xxx的当前提交；删除分支后，丢掉分支信息CONFLICT：产生冲突；删除分支后，保留分支信息”</td></tr><tr><td>git branch -d xxx</td><td>删除分支xxx</td><td></td></tr><tr><td><strong>解决冲突</strong></td><td></td><td></td></tr><tr><td>git log –graph –pretty=oneline –abbrev-commit</td><td>带参数的git log，查看分支合并图</td><td>删除分支后，保留分支信息</td></tr><tr><td><strong>“Fast forward”模式 no-ff</strong></td><td></td><td></td></tr><tr><td>git merge –no-ff -m “merge with no-ff” xxx</td><td>合并分支xxx，–no-ff：禁用Fast-forward“快进模式”</td><td>删除分支后，保留分支信息</td></tr><tr><td><strong>5.bug分支</strong></td><td></td><td></td></tr><tr><td>git stash</td><td>隐藏当前分支的工作现场</td><td></td></tr><tr><td>git stash list</td><td>查看stash隐藏的内容</td><td></td></tr><tr><td>git stash apply</td><td>恢复stash隐藏内容</td><td></td></tr><tr><td>git stash drop</td><td>删除stash内容</td><td></td></tr><tr><td>git stash pop</td><td>恢复并删除stash隐藏内容</td><td></td></tr><tr><td><strong>6.Github远程仓库</strong></td><td></td><td></td></tr><tr><td><strong>创建SSH Key</strong></td><td></td><td></td></tr><tr><td>ssh-keygen -t rsa –C “<a href="mailto:youremail@example.com" target="_blank" rel="noopener">youremail@example.com</a>”</td><td>创建SSH Key</td><td>id_rsa是私钥，不能泄露出去;id_rsa.pub是公钥，可以放心地告诉任何人”</td></tr><tr><td><strong>Github中添加SSH Key</strong></td><td></td><td></td></tr><tr><td><strong>添加远程库</strong></td><td></td><td></td></tr><tr><td><strong>a.先创建本地git仓库，再创建github仓库，两个仓库同步</strong></td><td></td><td></td></tr><tr><td>git remote add origin <a href="https://github.com/xxx/xxx.git" target="_blank" rel="noopener">https://github.com/xxx/xxx.git</a></td><td>添加github地址</td><td></td></tr><tr><td>git push -u origin master</td><td>第一次使用时执行该命令，将本地的master分支和远程的master分支关联起来，并把将其推送到远程”</td><td></td></tr><tr><td>git push origin master</td><td>将本地master分支的最新修改推送到github</td><td></td></tr><tr><td><strong>b.先创建github仓库，再从github仓库</strong></td><td></td><td></td></tr><tr><td>git clone <a href="https://github.com/xxx/xxx" target="_blank" rel="noopener">https://github.com/xxx/xxx</a></td><td></td><td></td></tr></tbody></table>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;从开始着手搭建博客，完整的学习Git，Markdown语法，到用Hexo搭建博客成功，再到后期在原有主题的基础增加功能性和视觉上的优化，折腾了三四天，总算看倒腾出了一个看上去基本满意的博客。由于时间关系，还有很多想法没有实现，后面会不断地改进和优化。今天先来说一说学习使用Git和Github。&lt;/p&gt;
    
    </summary>
    
      <category term="前端工具" scheme="https://baoyuzhang.github.io/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/"/>
    
    
      <category term="Git" scheme="https://baoyuzhang.github.io/tags/Git/"/>
    
      <category term="Github" scheme="https://baoyuzhang.github.io/tags/Github/"/>
    
      <category term="Hexo" scheme="https://baoyuzhang.github.io/tags/Hexo/"/>
    
  </entry>
  
</feed>
