diff --git a/pre_commit_hooks/requirements_txt_fixer.py b/pre_commit_hooks/requirements_txt_fixer.py
index 6190692..78103a1 100644
--- a/pre_commit_hooks/requirements_txt_fixer.py
+++ b/pre_commit_hooks/requirements_txt_fixer.py
@@ -1,4 +1,5 @@
 import argparse
+import re
 from typing import IO
 from typing import List
 from typing import Optional
@@ -10,6 +11,9 @@ FAIL = 1
 
 
 class Requirement:
+    UNTIL_COMPARISON = re.compile(b'={2,3}|!=|~=|>=?|<=?')
+    UNTIL_SEP = re.compile(rb'[^;\s]+')
+
     def __init__(self) -> None:
         self.value: Optional[bytes] = None
         self.comments: List[bytes] = []
@@ -17,11 +21,20 @@ class Requirement:
     @property
     def name(self) -> bytes:
         assert self.value is not None, self.value
+        name = self.value.lower()
         for egg in (b'#egg=', b'&egg='):
             if egg in self.value:
-                return self.value.lower().partition(egg)[-1]
+                return name.partition(egg)[-1]
+
+        m = self.UNTIL_SEP.match(name)
+        assert m is not None
+
+        name = m.group()
+        m = self.UNTIL_COMPARISON.search(name)
+        if not m:
+            return name
 
-        return self.value.lower().partition(b'==')[0]
+        return name[:m.start()]
 
     def __lt__(self, requirement: 'Requirement') -> int:
         # \n means top of file comment, so always return True,

requirements-txt-fixer does not parse all requirements
While working on #330 I noticed that the requirements-txt-fixer hook only parses a small subset of requirement specifiers. Take this example:

    pyramid-foo==1
    pyramid>=2

`pyramid` should sort before `pyramid-foo`, but the hook interprets the `>=2` as part of the name.

According to [PEP 508](https://www.python.org/dev/peps/pep-0508/) there are a couple of things that can be specified after the name (extras, versions, markers) so maybe an approach would be to use a regular expression to extract only the package name?
diff --git a/tests/requirements_txt_fixer_test.py b/tests/requirements_txt_fixer_test.py
index 17a9a41..fae5a72 100644
--- a/tests/requirements_txt_fixer_test.py
+++ b/tests/requirements_txt_fixer_test.py
@@ -33,9 +33,28 @@ from pre_commit_hooks.requirements_txt_fixer import Requirement
         (b'\nfoo\nbar\n', FAIL, b'bar\n\nfoo\n'),
         (b'\nbar\nfoo\n', PASS, b'\nbar\nfoo\n'),
         (
-            b'pyramid==1\npyramid-foo==2\n',
-            PASS,
-            b'pyramid==1\npyramid-foo==2\n',
+            b'pyramid-foo==1\npyramid>=2\n',
+            FAIL,
+            b'pyramid>=2\npyramid-foo==1\n',
+        ),
+        (
+            b'a==1\n'
+            b'c>=1\n'
+            b'bbbb!=1\n'
+            b'c-a>=1;python_version>="3.6"\n'
+            b'e>=2\n'
+            b'd>2\n'
+            b'g<2\n'
+            b'f<=2\n',
+            FAIL,
+            b'a==1\n'
+            b'bbbb!=1\n'
+            b'c>=1\n'
+            b'c-a>=1;python_version>="3.6"\n'
+            b'd>2\n'
+            b'e>=2\n'
+            b'f<=2\n'
+            b'g<2\n',
         ),
         (b'ocflib\nDjango\nPyMySQL\n', FAIL, b'Django\nocflib\nPyMySQL\n'),
         (

pip install -e .[dev]
parse_log_pytest
requirements.txt
3.9
requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
cfgv==3.4.0
covdefaults==2.3.0
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
identify==2.6.9
iniconfig==2.1.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pre_commit==4.2.0
-e git+https://github.com/pre-commit/pre-commit-hooks.git@3d379a962d0f8bca3ad9bc59781c562b12f303b3#egg=pre_commit_hooks
pytest==8.3.5
PyYAML==6.0.2
ruamel.yaml==0.18.10
ruamel.yaml.clib==0.2.12
toml==0.10.2
tomli==2.2.1
virtualenv==20.29.3

name: pre-commit-hooks
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cfgv==3.4.0
      - covdefaults==2.3.0
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - identify==2.6.9
      - iniconfig==2.1.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pre-commit==4.2.0
      - pytest==8.3.5
      - pyyaml==6.0.2
      - ruamel-yaml==0.18.10
      - ruamel-yaml-clib==0.2.12
      - toml==0.10.2
      - tomli==2.2.1
      - virtualenv==20.29.3
prefix: /opt/conda/envs/pre-commit-hooks

tests/requirements_txt_fixer_test.py::test_integration[pyramid-foo==1\npyramid>=2\n-1-pyramid>=2\npyramid-foo==1\n] tests/requirements_txt_fixer_test.py::test_integration[a==1\nc>=1\nbbbb!=1\nc-a>=1;python_version>="3.6"\ne>=2\nd>2\ng<2\nf<=2\n-1-a==1\nbbbb!=1\nc>=1\nc-a>=1;python_version>="3.6"\nd>2\ne>=2\nf<=2\ng<2\n]
tests/requirements_txt_fixer_test.py::test_integration[-0-] tests/requirements_txt_fixer_test.py::test_integration[\n-0-\n] tests/requirements_txt_fixer_test.py::test_integration[# tests/requirements_txt_fixer_test.py::test_integration[foo\n# tests/requirements_txt_fixer_test.py::test_integration[foo\nbar\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[bar\nfoo\n-0-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[a\nc\nb\n-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[a\nc\nb-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[a\nb\nc-1-a\nb\nc\n] tests/requirements_txt_fixer_test.py::test_integration[#comment1\nfoo\n#comment2\nbar\n-1-#comment2\nbar\n#comment1\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment1\nbar\n#comment2\nfoo\n-0-#comment1\nbar\n#comment2\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment\n\nfoo\nbar\n-1-#comment\n\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[#comment\n\nbar\nfoo\n-0-#comment\n\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[\nfoo\nbar\n-1-bar\n\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[\nbar\nfoo\n-0-\nbar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[ocflib\nDjango\nPyMySQL\n-1-Django\nocflib\nPyMySQL\n] tests/requirements_txt_fixer_test.py::test_integration[-e tests/requirements_txt_fixer_test.py::test_integration[bar\npkg-resources==0.0.0\nfoo\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[foo\npkg-resources==0.0.0\nbar\n-1-bar\nfoo\n] tests/requirements_txt_fixer_test.py::test_integration[git+ssh://git_url@tag#egg=ocflib\nDjango\nijk\n-1-Django\nijk\ngit+ssh://git_url@tag#egg=ocflib\n] tests/requirements_txt_fixer_test.py::test_integration[b==1.0.0\nc=2.0.0 tests/requirements_txt_fixer_test.py::test_integration[a=2.0.0 tests/requirements_txt_fixer_test.py::test_requirement_object
pre_commit_hooks/requirements_txt_fixer.py
pre_commit_hooks/requirements_txt_fixer.py