Answers.Body: <p>Here's a solution completely ignoring the chess library, only requiring the pgn string as input:</p>
  
  <pre><code>def m2m(pgn, m1, m2):
  
      sub_var_level = 0
      idx_1 = idx_2 = len(pgn)
  
      for idx, char in enumerate(pgn):
     
          if char == '(':
              sub_var_level += 1
          elif char == ')':
              sub_var_level -= 1
      
          elif not sub_var_level:
              if pgn[idx:].startswith(' %d. ' % m1):
                  idx_1 = idx
              elif pgn[idx:].startswith(' %d. ' % (m2 + 1)):
                  idx_2 = idx
  
      return pgn[idx_1:idx_2]
  </code></pre>
  <p>Now you can call the function, e.g.</p>
  <blockquote>
  <p>&gt;&gt;&gt; m2m(pgn, 6, 10) <br />
  ' 6. Nc2 ( 6. e3 ) 6... Nf6 7. Nc3 Qe5 8. Bg2 Na6 9. O-O Be7 10. Ne3 O-O'</p>
  </blockquote>
  <blockquote>
  <p>&gt;&gt;&gt; m2m(pgn, 30, 35) <br />
  ' 30. f4 Qh1+ 31. Kf2 Qxa1 32. Kxg2 Bh3+ 0-1'</p>
  </blockquote>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-28T14:24:11.533Z
Answers.Text: This is great - I have a lot to learn!
Answers.UserDisplayName: Matt
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-28T21:53:29.537Z
Answers.Text: I just noticed: if you do not want the string to start with a space, you can return pgn[idx_1+1:idx_2]
Answers.UserDisplayName: Hauptideal
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-26T01:12:14.690Z
Answers.LastActivityDate: 2023-08-26T01:12:14.690Z
Answers.UserDisplayName: Hauptideal
Body: <p>Using <a href="https://python-chess.readthedocs.io/en/latest/pgn.html" rel="nofollow noreferrer">python chess</a>, I would like to be able to list specific moves from a pgn string. For instance, in this string:</p>
  <blockquote>
  <ol>
  <li>c4 e5 2. g3 c6 ( 2... d5 3. cxd5 ) 3. Nf3 e4 4. Nd4 d5 5. cxd5 Qxd5 6. Nc2 ( 6. e3 ) 6... Nf6 7. Nc3 Qe5 8. Bg2 Na6 9. O-O Be7 10. Ne3 O-O 11. a3 Re8 ( 11... Nc7 ) 12. b4 Ng4 13. Bb2 Qh5 14. h4 Bf6 ( 14... Nxe3 15. dxe3 f5 16. Qb3+ Kh8 17. Na4 Qg6 18. Qc2 Nc7 19. Bd4 ) 15. Qc2 Nxe3 16. dxe3 Bf5 17. Na4 Bxb2 ( 17... Bxh4 18. gxh4 ) 18. Nxb2 ( 18. Qxb2 Nc7 ) 18... Nc7 19. Nc4 Re6 20. Rfd1 Nd5 21. Rd4 ( 21. b5 g5 ) 21... h6 ( 21... g5 ) 22. Qd2 ( 22. Rad1 g5 ) 22... Rae8 23. Kh2 ( 23. Rxd5 ) 23... Bg4 24. Na5 ( 24. Re1 g5 ) 24... Rf6 25. Kg1 g5 26. Nxb7 ( 26. Qb2 Ree6 27. Bxe4 gxh4 28. Bf3 Rg6 29. Rxg4 Rxg4 30. Bxg4 Qxg4 ) 26... gxh4 27. Nc5 h3 28. Rxe4 ( 28. Nxe4 Rfe6 ) 28... hxg2 29. Rxe8+ Kg7 30. f4 Qh1+ 31. Kf2 Qxa1 32. Kxg2 Bh3+ 0-1</li>
  </ol>
  </blockquote>
  <p>I would like the first 5 moves and their variations (or a different set for example moves 6 to 10):</p>
  <blockquote>
  <ol>
  <li>c4 e5 2. g3 c6 ( 2... d5 3. cxd5 ) 3. Nf3 e4 4. Nd4 d5 5. cxd5 Qxd5</li>
  </ol>
  </blockquote>
  <p>The string is generated using a command like this:</p>
  <blockquote>
  <p>exporter = chess.pgn.StringExporter(headers=False, variations=False,
  comments=False)</p>
  <p>pgn_string = games<a href="https://python-chess.readthedocs.io/en/latest/pgn.html" rel="nofollow noreferrer">1</a>.accept(exporter)</p>
  <p>print(pgn_string)</p>
  </blockquote>
  
Tags: <programming><pgn><python>
Title: List specific moves from a pgn file using python chess.pgn
ThreadText: # List specific moves from a pgn file using python chess.pgn
  
  (Asked by: username_0 on 2023-08-25)
  
  Using [python chess](https://python-chess.readthedocs.io/en/latest/pgn.html), I would like to be able to list specific moves from a pgn string. For instance, in this string:
  
  > 1. c4 e5 2. g3 c6 ( 2... d5 3. cxd5 ) 3. Nf3 e4 4. Nd4 d5 5. cxd5 Qxd5 6. Nc2 ( 6. e3 ) 6... Nf6 7. Nc3 Qe5 8. Bg2 Na6 9. O-O Be7 10. Ne3 O-O 11. a3 Re8 ( 11... Nc7 ) 12. b4 Ng4 13. Bb2 Qh5 14. h4 Bf6 ( 14... Nxe3 15. dxe3 f5 16. Qb3+ Kh8 17. Na4 Qg6 18. Qc2 Nc7 19. Bd4 ) 15. Qc2 Nxe3 16. dxe3 Bf5 17. Na4 Bxb2 ( 17... Bxh4 18. gxh4 ) 18. Nxb2 ( 18. Qxb2 Nc7 ) 18... Nc7 19. Nc4 Re6 20. Rfd1 Nd5 21. Rd4 ( 21. b5 g5 ) 21... h6 ( 21... g5 ) 22. Qd2 ( 22. Rad1 g5 ) 22... Rae8 23. Kh2 ( 23. Rxd5 ) 23... Bg4 24. Na5 ( 24. Re1 g5 ) 24... Rf6 25. Kg1 g5 26. Nxb7 ( 26. Qb2 Ree6 27. Bxe4 gxh4 28. Bf3 Rg6 29. Rxg4 Rxg4 30. Bxg4 Qxg4 ) 26... gxh4 27. Nc5 h3 28. Rxe4 ( 28. Nxe4 Rfe6 ) 28... hxg2 29. Rxe8+ Kg7 30. f4 Qh1+ 31. Kf2 Qxa1 32. Kxg2 Bh3+ 0-1
  
  I would like the first 5 moves and their variations (or a different set for example moves 6 to 10):
  
  > 1. c4 e5 2. g3 c6 ( 2... d5 3. cxd5 ) 3. Nf3 e4 4. Nd4 d5 5. cxd5 Qxd5
  
  The string is generated using a command like this:
  
  > exporter = chess.pgn.StringExporter(headers=False, variations=False,
  > comments=False)
  >
  > pgn\_string = games[1](https://python-chess.readthedocs.io/en/latest/pgn.html).accept(exporter)
  >
  > print(pgn\_string)
  
  **Tags:** programming, pgn, python
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-08-26. Score: 0 | Accepted answer
  
  Here's a solution completely ignoring the chess library, only requiring the pgn string as input:
  
  ```
  def m2m(pgn, m1, m2):
  
      sub_var_level = 0
      idx_1 = idx_2 = len(pgn)
  
      for idx, char in enumerate(pgn):
     
          if char == '(':
              sub_var_level += 1
          elif char == ')':
              sub_var_level -= 1
      
          elif not sub_var_level:
              if pgn[idx:].startswith(' %d. ' % m1):
                  idx_1 = idx
              elif pgn[idx:].startswith(' %d. ' % (m2 + 1)):
                  idx_2 = idx
  
      return pgn[idx_1:idx_2]
  
  ```
  
  Now you can call the function, e.g.
  
  > >>> m2m(pgn, 6, 10)   
  > ' 6. Nc2 ( 6. e3 ) 6... Nf6 7. Nc3 Qe5 8. Bg2 Na6 9. O-O Be7 10. Ne3 O-O'
  
  > >>> m2m(pgn, 30, 35)   
  > ' 30. f4 Qh1+ 31. Kf2 Qxa1 32. Kxg2 Bh3+ 0-1'
  
  > **Comments:**
  > **username_0**: This is great - I have a lot to learn!  
  > **username_1**: I just noticed: if you do not want the string to start with a space, you can return pgn[idx_1+1:idx_2]  
  
  ---
  
  